非同期処理をするときに戻ってきた値をテストする方法の話 expectationとwaitForExpectations(https://developer.apple.com/documentation/xctest/xctestcase/1500748-waitforexpectations)を使う
XCTestでこんな感じで書くとテストが通ってしまう
import XCTest
func testAsynchronousFunction() {
asynchronousFunction { (name) in
XCTAssertEqual(name, "rocky")
XCTAssertEqual(name, "rocky3") // testされない. test全体としてsucceededに見えてしまう
}
}
func asynchronousFunction(_ completionHandler: @escaping (String) -> Void) -> Void {
let queue = DispatchQueue.global()
queue.async {
Thread.sleep(forTimeInterval: 1)
completionHandler("rocky")
}
}
やる場合には、expectationを作っておいて、callback内でfulfill()を呼んであげて、呼ばれなければテストが失敗するようにする
import XCTest
func testAsynchronousFunction() {
let functionAnswered = expectation(description: "asynchronous function")
asynchronousFunction { (name) in
XCTAssertEqual(name, "rocky")
XCTAssertEqual(name, "rocky3") // 想定通り、testがfailする
functionAnswered.fulfill()
}
waitForExpectations(timeout: 3, handler: nil) //すべてのexpectationがfulfillされるまで待つ.timeoutは3秒
}
func asynchronousFunction(_ completionHandler: @escaping (String) -> Void) {
let queue = DispatchQueue.global()
queue.async {
Thread.sleep(forTimeInterval: 1)
completionHandler("rocky")
}
}
外部API叩くときなんかはmockして実装したところのテストにフォーカスすべきではあるが、こういうのが使いたいときもある
waitForExpectationsで待つ分、多様するとテスト時間が長くなって良くない