Reputation: 17591
I want to test this method that doesn't return a value but I want to check if works fine. Can you give me some suggestions?
func login() {
if Utility.feature.isAvailable(myFeat) {
if self.helper.ifAlreadyRed() {
self.showWebViewController()
} else {
let firstVC = FirstViewController()
self.setRootController(firstVC)
}
} else {
let secondVC = SecondViewController()
self.setRootController(secondVC)
}
}
so what's the best approach to apply unit test here?
Upvotes: 8
Views: 2749
Reputation: 62062
Testing side effects is one approach. But for an example like the code in question, I actually prefer a subclass-and-expect approach.
Your code has three different paths.
So assuming this login()
function is part of FooViewController
, one possibility is writing tests that follow this format:
func testLoginFeatureAvailableAndNotAlreadyRed() {
class TestVC: FooViewController {
let setRootExpectation: XCTExpectation
init(expectation: XCTExpectation) {
setRootExpectation = expectation
super.init()
}
override func setRootController(vc: UIViewController) {
defer { setRootExpectation.fulfill() }
XCTAssertTrue(vc is FirstViewController)
// TODO: Any other assertions on vc as appropriate
// Note the lack of calling super here.
// Calling super would inaccurately conflate our code coverage reports
// We're not actually asserting anything within the
// super implementation works as intended in this test
}
override func showWebViewController() {
XCTFail("Followed wrong path.")
}
}
let expectation = expectationWithDescription("Login present VC")
let testVC = TestVC(expectation: expectation)
testVC.loadView()
testVC.viewDidLoad()
// TODO: Set the state of testVC to whatever it should be
// to expect the path we set our mock class to expect
testVC.login()
waitForExpectationsWithTimeout(0, handler: nil)
}
Upvotes: 5