i'm quite new to XCTest, i have structured my code in Model, View, Controller
So controller will take data from Model and once got data, Controller will update View. So i have my Controller and view as follow
Controller:
func loadData() {
Model.provideData { response in
if response != nil {
view.refresh()
}
}
}
View:
func refresh() {
isViewLoaded = true
}
and here is my XCTest
func testLoadData() {
let sut = Controller()
let mockView = View()
mockView.setController(controller: sut)
controller.loadData()
/** HERE is the problem, because it is a ASYNC call, i need to wait for the flag is set **/
XCTAssertTrue(mockView.isViewLoaded, "isViewLoaded equals to true")
}
i know i can
let expectation = expectation(description: "wait for isViewLoaded set to true")
but where should i put the expectation.fulfill()
?
waitForExpectation(timeout: 5, handler: nil)
Any help is appreciated. Thanks
You need your loadData
to have a completion handler and hence be able to notify its callers when the async function is complete.
func loadData(completion: @escaping () -> Void) {
Model.provideData { response in
if response != nil {
view.refresh()
}
completion()
}
}
And then in your test, do expectation.fulfill
in the completion
of loadData
.
func testLoadData() {
let expectation = expectation(description: "wait for isViewLoaded set to true")
let sut = Controller()
let mockView = View()
mockView.setController(controller: sut)
controller.loadData {
expectation.fulfill()
}
waitForExpectation(timeout: 5, handler: nil)
XCTAssertTrue(mockView.isViewLoaded, "isViewLoaded equals to true")
}