单元测试时托管对象上下文为零restkit

Posted

技术标签:

【中文标题】单元测试时托管对象上下文为零restkit【英文标题】:managed object context nil restkit while unitTesting 【发布时间】:2015-06-21 13:00:39 【问题描述】:

我正在使用使用 cocoapods 集成的 restkit (0.24.1) 为我的应用程序开发单元测试:

pod "RestKit/Testing", "~> 0.24.1"
pod "RestKit", "~> 0.24.1"

我收到一条错误消息,提示 managedObjectContext 为 nil。我不敢苟同,因为我已经有很多使用相同对象上下文的单元测试,而且它们似乎都可以工作......:/

Restkit 设置:

lazy var persistentStoreCoordinator: RKManagedObjectStore? = 
    var coordinator = RKManagedObjectStore(managedObjectModel: self.managedObjectModel)
    self.objectManager!.managedObjectStore = coordinator

    coordinator.createPersistentStoreCoordinator()

    var storePath: NSString = RKApplicationDataDirectory().stringByAppendingPathComponent(self.storeFilename)

    var e: NSError?
    coordinator.addSQLitePersistentStoreAtPath(storePath as String, fromSeedDatabaseAtPath: nil, withConfiguration: nil,
        options: [
            NSInferMappingModelAutomaticallyOption: true,
            NSMigratePersistentStoresAutomaticallyOption: true
        ], error: &e)

    if(e != nil)
            var error: NSError? = nil
            coordinator = nil
            // Report any error we got.
            let dict = NSMutableDictionary()
            dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
            dict[NSLocalizedFailureReasonErrorKey] = "There was an error creating or loading the application's saved data."
            dict[NSUnderlyingErrorKey] = error
            error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict as [NSObject : AnyObject])
            Logger.Error("Serious error \(error), \(error!.userInfo)")
            abort()
    

    coordinator.createManagedObjectContexts()
    coordinator.managedObjectCache = RKInMemoryManagedObjectCache(managedObjectContext: coordinator.persistentStoreManagedObjectContext)

    return coordinator
    ()

单元测试:

class TestRestMappers: XCTestCase 

    let rootEndpoint = RootEndpoint()

    override func setUp() 
        super.setUp()

        let testTargetBundle = NSBundle(identifier: "anita-borg.malaria-iosTests")
        RKTestFixture.setFixtureBundle(testTargetBundle)
    

    func testRootEndpointMapper() 
        let parsedJson: AnyObject? = RKTestFixture.parsedObjectWithContentsOfFixture("api.json")

        let mapping = rootEndpoint.mapping

        let test = RKMappingTest(forMapping: mapping, sourceObject: parsedJson, destinationObject: nil)

        test.addExpectation(RKPropertyMappingTestExpectation(sourceKeyPath: "users", destinationKeyPath: "users"))

        XCTAssertTrue(test.evaluate)
    

我从控制台得到的错误信息是:

*** Assertion failure in -[RKMappingTest dataSourceForMappingOperation:], (...): error: 
-[malaria_iosTests.TestRestMappers testRootEndpointMapper] : XCTAssertTrue failed: throwing "Cannot test an `RKEntityMapping` with a nil managed object context." - 

Test Case '-[malaria_iosTests.TestRestMappers testRootEndpointMapper]' failed (0.010 seconds).

我连接商店的映射的 sn-p:

let managedObjectStore: RKManagedObjectStore = CoreDataStore.sharedInstance.persistentStoreCoordinator!
let rootMap = RKEntityMapping(forEntityForName: name, inManagedObjectStore: managedObjectStore)

我已经在很多地方搜索了问题的根源,但似乎找不到解决方案。

提前谢谢你

编辑:

NSManagedObjectContext:

lazy var backgroundContext: NSManagedObjectContext? = 
    let coordinator = self.store.persistentStoreCoordinator?.persistentStoreCoordinator
    if coordinator == nil 
        return nil
    

    var backgroundContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
    backgroundContext.persistentStoreCoordinator = coordinator
    return backgroundContext
    ()

【问题讨论】:

虽然您没有设置managedObjectContexttest 我不明白,我认为它是用于生产和单元测试的核心数据/restkit 堆栈的横向。那我怎样才能提供一个测试呢? 您有一个显式映射测试,该映射没有显式使用/保留用于创建它的实体的 MOC,因此您需要使用上下文配置测试以使用 我明白了。但是,当我调用 coordinator.createManagedObjectContexts() 时,这不是涵盖了吗?通过文档:“为接收者创建持久存储和主队列托管对象上下文” 创建上下文,当然。你的意思是你期待测试出去寻找一个 MOC 来使用? 【参考方案1】:

测试需要配置。一般来说,你应该假设如果你没有明确地给测试一些信息,那么它就没有任何信息。因此,您需要为测试提供一个可以使用的上下文(在您的特定情况下还可能是一个数据源)。

test.managedObjectContext = ...

【讨论】:

我明白了!有效!感谢 Wain 的快速回答和反馈!我是新来的,我怎么给你点赞? (并将其标记为正确答案)编辑:标记为已解决:)

以上是关于单元测试时托管对象上下文为零restkit的主要内容,如果未能解决你的问题,请参考以下文章

运行第二个单元测试时核心数据实体名称为零

在 iOS 开发中使用 OCUnit 对 XCode 4.5 中的核心数据对象进行单元测试

为啥即使单元测试全部通过,我的代码覆盖率也为零?

单元测试 (XCTest) NIB Outlets 为零

自托管 web api 并从单元测试项目中访问它

单元测试(Kiwi):调用 loadView 和 viewDidLoad 后,测试中的属性始终为零