mardi 1 décembre 2015

Instantiating UIViewController in a test

I'm working in Swift 2, and would like to test functions within my view controller. I've made a dependency injection-like service which looks like this:

extension UIViewController: {
    func getDbService() -> IDbService {
        let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
        return DbService(context: context)
    }
}

With this, I can set AppDelegate's context as a mocked one for test purposes. However, the problem arises when I try to instantiate a view controller. Here's the code:

class LoginViewController: UIViewController {
    var token: String?

    override func viewDidLoad() {
        super.viewDidLoad()
        let dbService = getDbService() 
        self.token = dbService.getToken() 
        //....do stuff with token 
    }
}

I instantiate the test like so:

class LoginViewControllerTests: XCTestCase {
    func testTokenExists() {
        let mockContext = MockContextUtils.getMockContext()
        let mockDbService = DbService(context: mockContext)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        appDelegate.dbService = mockDbService
        let sut = LoginViewController()
        let _ = sut.view // Apparently this renders the view; I set a breakpoint, viewDidLoad is called
        XCTAssertNotNil(sut.token) // FAILS, BECAUSE APPDELEGATE CALLS APP DATABASE, AND NOT MOCK.
    }
}

The reason this simple test fails is because LoginViewController has no idea what app delegate is. Is there a way to introduce that in the initialization phase?

Aucun commentaire:

Enregistrer un commentaire