NSManagedObject 子类模拟

Posted

技术标签:

【中文标题】NSManagedObject 子类模拟【英文标题】:NSManagedObject subclass mocking 【发布时间】:2017-02-17 19:44:04 【问题描述】:

我正在编写 XCTest 案例,但我被困在一个地方。 我的主要目标中有一个 Class Car,它是 NSManagedObject 的子类。我正在创建模拟,它将具有 Car 类的对象数组。但是每当我对 Car 的元素使用 setter 时,它就会崩溃。

在主要目标中

class Car: NSManagedObject 

    @NSManaged var name: String


在测试目标中

class CarTests: XCTestCase 



    func testCar() 

        let car = getMyCar()
        // Some asserts here

    

    func getMyCar() -> Car 
        let car: Car = Car.Init()
        car.name = "Ferrari"

        return car
    


当我设置汽车名称时它崩溃了。知道如何创建汽车对象的模拟数据吗?

错误 - 失败:捕获“NSInvalidArgumentException”、“-[MyProject.Car setName:]:无法识别的选择器发送到实例 0x310434347f200”

【问题讨论】:

【参考方案1】:

您可以在测试目标的新存根子类中完全覆盖 NSManagedObject 子类属性 getter。 self.init() 工作正常。

class StubCar: Car 
    convenience init(name: String = "") 
        self.init()
        self.stubbedName = name
    

    var stubbedName: String = ""
    override var name: String 
        set 
        get 
            return stubbedName
        
    

现在测试中的使用只是let stubCar = StubCar(),并且当生产代码访问属性时没有与 CoreData 相关的崩溃,您根本不需要设置完整的内存 CoreData 堆栈。如果需要,也可以覆盖 setter。这假设您已正确抽象出数据层,因此您可以将这些模型注入到需要它们的地方并编写测试。

【讨论】:

【参考方案2】:

这是因为 Car 是一个 NSManagedObject 子类,这意味着它必须使用其指定的初始化程序进行初始化:initWithEntity:insertIntoManagedObjectContext:

在这篇小文章中,您可以找到有关使用 NSMangedObjects 和 XCTests 的更多信息: https://www.andrewcbancroft.com/2015/01/13/unit-testing-model-layer-core-data-swift/

【讨论】:

以上是关于NSManagedObject 子类模拟的主要内容,如果未能解决你的问题,请参考以下文章

NSmanagedobject 的子类的子类

当一对多相关的 NSManagedObject 子类发生更改时,如何更新 NSManagedObject 子类?

NSManagedObject 验证和子类

新的 NSManagedObject 子类与新的 NSObject 子类?

NSManagedObject 子类属性

子类化一个 NSManagedObject 子类