XCode 7 Beta/Swift 2 中的单元测试核心数据
Unit Testing Core Data in XCode 7 Beta/Swift 2
简而言之:
我正在尝试为 XCode 7/Swift 2 中的核心数据模型编写单元测试。但是,一个简单的测试,例如测试模型中的行数等于我知道它失败了(我知道有一行,但测试看到 none)。我最好的猜测是我得到了 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).
长格式:
以下是设置我能想到的最小的可重现示例的步骤:
- 简单模型:一个
Entity
(Person
) 和一个 Attribute
(name
,键入 String
)。 Person
是唯一的,name
是非可选的。
- 创建子class(编辑器 > 创建 NSManagedObject 子class...)
- (在
Person.swift
中注释掉 @objc(Person)
以避免构建错误。)
- 向模型添加一行。 (只有 运行 获取实体并保存一次的代码——在随后的 运行 中将其注释掉,以避免由于
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.") }
}
}
- 然后我将
Person
subclass 文件添加到构建阶段中的 SOTestTests
(元,我知道),根据 managedObjectContext
上的示例设置 Andrew Bancroft 的(优秀)站点(带有 Swift 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.") }
}
}
- 通过选择
SOTestTests
创建新方案,并将 SOTest.app
可执行文件添加到 运行 方案。
当我运行这个时,ViewController
class打印出只有一行,但是测试打印出零行,测试失败。
知道我做错了什么吗?
只需导入实际项目即可访问 AppDelegate 和其他 类。
@testable import SOTest
无需将所有内容添加到测试目标。
简而言之:
我正在尝试为 XCode 7/Swift 2 中的核心数据模型编写单元测试。但是,一个简单的测试,例如测试模型中的行数等于我知道它失败了(我知道有一行,但测试看到 none)。我最好的猜测是我得到了 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).
长格式:
以下是设置我能想到的最小的可重现示例的步骤:
- 简单模型:一个
Entity
(Person
) 和一个Attribute
(name
,键入String
)。Person
是唯一的,name
是非可选的。 - 创建子class(编辑器 > 创建 NSManagedObject 子class...)
- (在
Person.swift
中注释掉@objc(Person)
以避免构建错误。) - 向模型添加一行。 (只有 运行 获取实体并保存一次的代码——在随后的 运行 中将其注释掉,以避免由于
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.") }
}
}
- 然后我将
Person
subclass 文件添加到构建阶段中的SOTestTests
(元,我知道),根据managedObjectContext
上的示例设置 Andrew Bancroft 的(优秀)站点(带有 Swift 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.") }
}
}
- 通过选择
SOTestTests
创建新方案,并将SOTest.app
可执行文件添加到 运行 方案。
当我运行这个时,ViewController
class打印出只有一行,但是测试打印出零行,测试失败。
知道我做错了什么吗?
只需导入实际项目即可访问 AppDelegate 和其他 类。
@testable import SOTest
无需将所有内容添加到测试目标。