【问题标题】:Unit Testing Core Data in XCode 7 Beta/Swift 2XCode 7 Beta/Swift 2 中的单元测试核心数据
【发布时间】:2015-10-24 02:36:18
【问题描述】:

简而言之:

我正在尝试在 XCode 7/Swift 2 中为 Core Data 模型编写单元测试。但是,一个简单的测试(例如测试模型中的行数是否等于我所知道的行数)失败了(我知道有一行,但测试没有看到)。我最好的猜测是我得到了一个不同的(干净的?)版本的managedObjectContext,但我不确定如何获得与应用程序相同的版本。除了下面描述的技术(按照 Andrew Bancroft 网站上的链接说明),我尝试将应用程序委托添加到 SOTestTests 并获取managedObjectContext,如下所示...

let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

...但是我得到一个错误,XCode [c]ould not cast value of type 'SOTest.AppDelegate' (0x25bb8) to 'SOTestTests.AppDelegate' (0x2c7bb78).

长格式:

以下是设置我能想到的最小可重现示例的步骤:

  1. 简单模型:一个EntityPerson)和一个Attributename,输入String)。 Person 是唯一的,name 是非可选的。
  2. 创建子类(编辑器 > 创建 NSManagedObject 子类...)
  3. (注释掉Person.swift 中的@objc(Person) 以避免生成错误。)
  4. 向模型添加一行。 (只运行获取实体并保存一次的代码——在后续运行时将其注释掉,以避免由于unique 属性而出现冲突错误。)这是执行此操作的ViewController
import UIKit
import CoreData

class ViewController: UIViewController {

    let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

    override func viewDidLoad() {
        super.viewDidLoad()

        // Put a new person in the model.
        let newPerson = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: self.managedObjectContext) as! Person
        newPerson.name = "Harper Lee"

        // Save it
        do { try self.managedObjectContext.save()
        } catch _ { NSLog("There was a problem saving to the database.") }

        // Sanity check
        let fetchRequest = NSFetchRequest(entityName:"Person")

        do {
            let fetchedResults = try managedObjectContext.executeFetchRequest(fetchRequest) as? [Person]
            NSLog("Number of rows (App): \(fetchedResults!.count)") // 1
        } catch _ { NSLog("Well...that went badly.") }
    }
}
  1. 然后我将Person 子类文件添加到构建阶段中的SOTestTests(元,我知道),根据Andrew Bancroft(优秀)网站上的示例设置managedObjectContext(带有用于Swift 的mod 2),并编写测试检查是否有一行:
import XCTest
import CoreData

class SOTestTests: XCTestCase {

    var managedObjectContext: NSManagedObjectContext!

    func setUpInMemoryManagedObjectContext() -> NSManagedObjectContext {
        let managedObjectModel = NSManagedObjectModel.mergedModelFromBundles([NSBundle.mainBundle()])!

        let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)

        do {
            try persistentStoreCoordinator.addPersistentStoreWithType(NSInMemoryStoreType, configuration: nil, URL: nil, options: nil)
        } catch _ { NSLog("Problem adding the Persistent Store Coordinator") }

        let managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator

        return managedObjectContext
    }

    override func setUp() {
        super.setUp()

        self.managedObjectContext = self.setUpInMemoryManagedObjectContext()

    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testExample() {
        // Check the number of rows in NUT_DATA
        do {
            let fetchRequest = NSFetchRequest(entityName:"Person")
            let fetchedResults = try managedObjectContext.executeFetchRequest(fetchRequest) as? [Person]
            print("Number of rows (Test): \(fetchedResults!.count)") // Prints 0
            XCTAssert(1 == fetchedResults!.count, "Incorrect number of rows in `Person` entity.")
        } catch _ { NSLog("Error fetching the entity Person.") }
    }
}
  1. 通过选择SOTestTests 创建一个新方案,并将SOTest.app 可执行文件添加到运行方案中。

当我运行它时,ViewController 类打印出只有一行,但测试打印出零行,测试失败。

任何想法我做错了什么?

【问题讨论】:

    标签: unit-testing core-data swift2 xcode7


    【解决方案1】:

    只需导入实际项目即可访问 AppDelegate 和其他类。

    @testable import SOTest
    

    无需将所有内容添加到测试目标。

    【讨论】:

    • 如果我导入 SOTestlet managedObjectContext = (UIApplication.sharedApplication().delegate as! SOTest.AppDelegate).managedObjectContext,我会收到一个错误,指出存在 No type named AppDelegate in module SOTest...
    • 在一个普通的 vanilla 项目中,它可以与您的确切托管对象上下文行一起使用而不会出错。请注意,最新的 Xcode 会自动执行上述导入,如下所示:@testable import SOTest
    • @testable import SOTest 添加到我的SOTestTests 课程中就可以了。由于某种原因,它无法将数组转换为[Person](我不得不将其更改为[NSManagedObject]),但现在测试通过了!谢谢!
    • 对于最后一个问题,请考虑this answer
    • 不错!更改为[SOTest.Person] 做到了。如果可以的话,我会投票两次。 :-)
    猜你喜欢
    • 2015-10-28
    • 2014-08-31
    • 2015-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多