MeMTn
MeMTn

Reputation: 93

Unit Test Crash when the tested function calls AppDelegate + managedObject

I am stock with the following problem: I am programming an app in swift. I have a class function (mapCategories) of a managed object (called Category) that I want to Unit test (XCTest).

myCategoryFunction gets an NSDictionary and maps its content in to a list of Categories [Category] and returns it. to do the mapping i had to create Category objects using the following code:

    class func mapCategories(myDictionary: NSDictionary!) -> [Category]{
        var categories: [Category] = []
        /* 
              ... some code here.
       */       
                let appDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)

                let managedObjectContext = appDelegate.managedObjectContext
                let entityDescription = NSEntityDescription.entityForName("Category", inManagedObjectContext: managedObjectContext!)
                var category = Category(entity: entityDescription!, insertIntoManagedObjectContext: managedObjectContext!)
      /* 
             ... some code here.
      */       
       return Categories
}

when i run the application, the code runs fine and works as intended but when i run the unit test of this function it crashes.

1st i get the following error:

AppDelegate error

which occurs in the following line:

let appDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)

and when i continue the program execution, it crashes when getting the managedObjectContext as follows:

managedObjectContext Error - EXC_BAD_ACCESS

I tried to find a solution or a workaround and tried the following:

UIApplication.sharedApplication().delegate as AppDelegate causes EXC_BAD_ACCESS using it on swift unit test

but it didn't work. Does anyone have a solution that works?

thanks in advance,

Upvotes: 2

Views: 2013

Answers (2)

Sushant
Sushant

Reputation: 470

With swift2 you don't need to make your methods and classes public, you can use,

@testable import {main module} 

Only caveat is that you need to keep your Host Application property point to main app bundle and toggle Enable Testability = Yes under your test target build settings.

Upvotes: 0

Doug Richardson
Doug Richardson

Reputation: 10811

As the stack trace indicates, the unconditional cast (the line with as AppDelegate) is failing. The question you linked to contains the solution to this problem.

My guess is the reason it didn't work for you is because you forgot to remove AppDelegate.swift from your unit test bundle target. Assuming you forgot, you now have two definitions for AppDelegate: one in your unit test bundle and one in your application bundle. The unconditional cast fails because your trying to cast the AppDelegate defined in your application to the AppDelegate defined in your unit test bundle.

To fix this, Control+Click on AppDelegate.swift and select Show File Inspector and then make sure under Target Memebership that the only checkbox is next to your application, and there is no check next to your unit test bundle.

enter image description here

The second issue you're seeing with the managed object context is just a consequence of the first issue.

Upvotes: 1

Related Questions