2

This is start of my XCTestCase class:

var moc: NSManagedObjectContext!

    override func setUp() {
        super.setUp()

        moc = self.setUpInMemoryManagedObjectContext()
        self.fillManagedObjectContextWithExampleData(moc)
    }

    func setUpInMemoryManagedObjectContext() -> NSManagedObjectContext {

        let modelName = "ProjectApp"
        let modelURL = NSBundle.mainBundle().URLForResource(modelName, withExtension:"momd")!
        let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)!

        let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)
        persistentStoreCoordinator.addPersistentStoreWithType(NSInMemoryStoreType, configuration: nil, URL: nil, options: nil, error: nil)

        let managedObjectContext = NSManagedObjectContext()
        managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator

        return managedObjectContext
    }

    func fillManagedObjectContextWithExampleData(context: NSManagedObjectContext) {
        // var firstSC = NSEntityDescription..insertNewObjectForEntityForName("StaticContent", inManagedObjectContext: context) as! StaticContent
        var staticContentEntity = NSEntityDescription.entityForName("StaticContent", inManagedObjectContext: context)!

        var firstSC = StaticContent(entity: staticContentEntity, insertIntoManagedObjectContext: context)
        firstSC.name = "First Name"

        var secondSC = StaticContent(entity: staticContentEntity, insertIntoManagedObjectContext: context)
        secondSC.name = "Second Name"

        var error: NSError? = nil

        if context.save(&error) {
            return
        }
    }

I just want to create managedObjectContext (in memory, just for testing) and fill it with example data. So I could use:

managedObjectContext.executeFetchRequest(fetchRequest, error: nil) as! [StaticContent]

in my unit tests. It executes but when I call function which takes [StaticContent] I got an error:

fatal error: NSArray element failed to match the Swift Array Element type

So what is a problem with this? My function which I call works fine. When I using it in my app and not in unit tests I don't have problem. So what I am doing wrong?

Libor Zapletal
  • 12,142
  • 18
  • 79
  • 165
  • Can you post the code where you are getting the error? – e1985 Jul 01 '15 at 14:28
  • 1
    And btw, this may have something to do with the entity's managedObjectClassName being different in your test target: if your include your manage object subclass in your test target, its class name would be YourTestTarget.StaticContent... It can be solved with this workaround: https://gist.github.com/efa85/d82cc8fb0358e970e1e4 – e1985 Jul 01 '15 at 14:36
  • Thanks, I found similar code in another stackoverflow question. I was searching for solution for hour and then after I post my question I found it. – Libor Zapletal Jul 01 '15 at 14:38

2 Answers2

2

I really don't like to answer my question but I have found an answer and I want help the others. I found a part of code which changes entities class names according to which target they are run. So I have added these lines of code where I create NSManagedObjectModel and it helps:

    // Create the module name
    let moduleName = "ProjectAppTests"

    // Create a new managed object model with updated entity class names
    var newEntities = [] as [NSEntityDescription]
    for (_, entity) in enumerate(managedObjectModel.entities) {
        let newEntity = entity.copy() as! NSEntityDescription
        newEntity.managedObjectClassName = "\(moduleName).\(entity.name)"
        newEntities.append(newEntity)
    }
    let newManagedObjectModel = NSManagedObjectModel()
    newManagedObjectModel.entities = newEntities

    let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: newManagedObjectModel)

Don't know why it is so complicated with Class name in Core Data using Swift. But it helps and it's working now.

Libor Zapletal
  • 12,142
  • 18
  • 79
  • 165
0

in swift 3.0:

func setUpInMemoryManagedObjectContext() -> NSManagedObjectContext {
        let moduleName = "Model"
        do {
            let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
            let modelURL = Bundle.main.url(forResource: moduleName, withExtension:"momd")
            let newObjectModel = NSManagedObjectModel.init(contentsOf: modelURL!)
            let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel : newObjectModel!)
            try  persistentStoreCoordinator.addPersistentStore(ofType: NSInMemoryStoreType, configurationName: nil, at: nil, options: nil)

            managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator
            return managedObjectContext
        } catch let error as NSError {
            logErr(error.localizedDescription)
            XCTFail()
        }
        XCTFail("failed to created mocked coreData (inMemroy)")
        return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
    } 
func fillManagedObjectContextWithExampleData(context: NSManagedObjectContext) {
//lets assume you got some Food POJO class
    do {
        let foodJson: NSDictionary = ["id" : "1" , "foodId" : "1" , "displayName": "Pizza"]
        let firstFood = try Food.createOrUpdate(dict: foodJson, inManagedObjectContext: context)
        try  context.save()
        return
    } catch let error as NSError {
        logErr(error.localizedDescription)
    }
}

taitelman
  • 572
  • 4
  • 9