NSManagedObject 子类模拟
NSManagedObject subclass mocking
我正在编写 XCTest 案例,但我被困在一个地方。
我的主要目标中有一辆 Class 汽车,它是 NSManagedObject 的子 class。我正在创建模拟,它将包含 Car class 的对象数组。但是每当我对 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”
这是因为 Car 是 NSManagedObject 的子类,这意味着它必须使用其指定的初始化程序进行初始化:initWithEntity:insertIntoManagedObjectContext:
。
在这篇小文章中,您可以找到有关使用 NSMangedObjects 和 XCTests 的更多信息:
https://www.andrewcbancroft.com/2015/01/13/unit-testing-model-layer-core-data-swift/
您可以在测试目标的新存根子类中完全覆盖 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 。这假设您已正确抽象出数据层,因此您可以在需要的地方注入这些模型并编写测试。
我正在编写 XCTest 案例,但我被困在一个地方。 我的主要目标中有一辆 Class 汽车,它是 NSManagedObject 的子 class。我正在创建模拟,它将包含 Car class 的对象数组。但是每当我对 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”
这是因为 Car 是 NSManagedObject 的子类,这意味着它必须使用其指定的初始化程序进行初始化:initWithEntity:insertIntoManagedObjectContext:
。
在这篇小文章中,您可以找到有关使用 NSMangedObjects 和 XCTests 的更多信息: https://www.andrewcbancroft.com/2015/01/13/unit-testing-model-layer-core-data-swift/
您可以在测试目标的新存根子类中完全覆盖 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 。这假设您已正确抽象出数据层,因此您可以在需要的地方注入这些模型并编写测试。