我有一组NSManagedObject
使用的ClassToBeTested
子类。
ClassToBeTested
仅在NSManagedObject
子类的几个属性上运行,不需要关系或整个CoreData堆栈。
我可以通过常规方式以相同方式在测试中使用相同的对象吗?
let template = CoreDataClass()
template.name = randomString(length: 40) // This fails!
templates.append(template)
当前它因错误而失败:
失败:捕获到“ NSInvalidArgumentException”,“-[CoreDataClass setTemplate_name:]:无法识别的选择器已发送到实例 0x600000af4c40“
答案 0 :(得分:1)
尽管我尝试执行此操作时遇到了另一个错误(未调用指定的初始化程序),但是在两种情况下,您的问题的答案都是:不,您不能这样做。
但是,如今有了NSPersistentContainer,使用单例内存Core Data Stack进行此类测试很容易。在测试包中包含数据模型,然后将其放入测试的全局范围:
var sharedTestContext: NSManagedObjectContext = {
// Swift is smart enough to execute this only once.
let container = NSPersistentContainer(name: "<YourDataModelName>")
let description = NSPersistentStoreDescription()
description.type = NSInMemoryStoreType
container.persistentStoreDescriptions = [description]
container.loadPersistentStores { (description, error) in
if let error = error {
fatalError("Failed to load store for test: \(error)")
}
}
return container.newBackgroundContext()
}()
并定义一个特殊的托管对象初始化程序进行如下测试:
/**
Initializes a managed object for testing
- important: This assumes your managed object subclass name is the same
as its entity name.
*/
public extension NSManagedObject {
convenience init(testContext: NSManagedObjectContext?) {
let context = testContext ?? sharedTestContext
/* The following contraption is necessary to avoid warning:
"Multiple NSEntityDescriptions claim the NSManagedObject subclass"
For explanation see:
https://stackoverflow.com/questions/51851485/multiple-nsentitydescriptions-claim-nsmanagedobject-subclass */
let name = String(describing: type(of: self))
let entity = NSEntityDescription.entity(forEntityName: name, in: context)!
self.init(entity: entity, insertInto: context)
}
}
现在您可以这样创建测试对象:
let template = CoreDataClass(testContext: nil)