I am trying to start unit testing on my swift iOS app but have run in to a total road block. I cannot seem to access anything that uses my appDelegate.
My appDelegate has a UserController
object which stores and manages the logged on user and it's various pieces of data. In order to simplify calling the userController
I created a custom subclass of NSObject
which all my model classes subclass. In it it has
let userController : UserController = (UIApplication.sharedApplication().delegate as! AppDelegate).userController
This line causes a SIGABRT exception whenever i try and test one of the subclassing models.
Could not cast value of type 'MyProject.AppDelegate' to 'MyProjectionTests.AppDelegate'.
I have tried removing AppDelegate from the test target, but this then gives me AppDelegate is undefined. I have tried adding import MyProject
into the top of the test file, but that didn't work either.
I have seen two other solutions:
Make the app delegate functions private - I am really loathed to do something like this. What is the point of testing if I am having to change my code specifically for testing.
Implement a testing app delegate and use that - again whats the point in testing if I'm not testing whats in the project.
Does anyone have a solution. Unit testing in Swift is proving to be a total headache after how easy RSpec is with rails
You can't add AppDelegate.swift
to the test target.
That causes the class to be created also at test target namespace and it will be a duplicate.
When the AppDelegate
object is unwrapped on the test target if fails because the object belongs to the version of the class AppDelegate
defined on the main target, but is the code is trying to unwrap the object as if it belongs to the version defined on the test target.
What it is needed is to enable the main target has a module so all of his classes can be imported into the test code, like any kit.
To define main target as module do this:
Then import the module and access the object do like this:
import UIKit
import XCTest
import MyApp
class MyAppTests: XCTestCase {
func testExample() {
let userController : UserController = (UIApplication.sharedApplication().delegate as! AppDelegate).userController
//or explicitly referencing the module
let userController : MyApp.UserController = (UIApplication.sharedApplication().delegate as! AppDelegate).userController
}
}
}
Class AppDelegate
and property userController
has to be made public.
If you already are using Swift 2.0 you can use testable attribute instead of changing the isolation level. Check this tutorial to see how.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With