In a Nutshell:
I'm trying to write a unit test for a Core Data model in XCode 7/Swift 2. However, a simple test such as testing that the number of rows in the model is equal to what I know it to be fails (I know there to be one row, but the test sees none). My best guess is that I'm getting a different (clean?) version of managedObjectContext
, but I'm not sure how to get the same version as the app. Besides the technique described below (following the linked instructions on Andrew Bancroft's site), I tried adding the application delegate to SOTestTests and getting the managedObjectContext
as follows...
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
...but I then get an error that XCode [c]ould not cast value of type 'SOTest.AppDelegate' (0x25bb8) to 'SOTestTests.AppDelegate' (0x2c7bb78).
Longform:
Here are the steps to set up the smallest reproducible example I could come up with:
- Simple model: One
Entity
(Person
) with oneAttribute
(name
, typeString
).Person
is unique,name
is non-optional. - Create a subclass (Editor > Create NSManagedObject Subclass...)
- (Comment out
@objc(Person)
inPerson.swift
to avoid a build error.) - Add a single row to the model. (Only run the code that gets an entity and saves it once--comment it out on subsequent runs to avoid getting a conflict error due to the
unique
property.) Here's theViewController
that's doing this:
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.") }
}
}
- I then add the
Person
subclass files toSOTestTests
(meta, I know) in Build Phases, setup themanagedObjectContext
according to the example on Andrew Bancroft's (excellent) site (with mods for Swift 2), and write the test checking if there is one row:
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.") }
}
}
- Create a new scheme by selecting
SOTestTests
, and addtheSOTest.app
executable to the run scheme.
When I run this, the ViewController
class prints out that there is a single row, but the test prints out zero rows, and the test fails.
Any ideas what I'm doing wrong?
Aucun commentaire:
Enregistrer un commentaire