動機
いくつかの非同期処理を挟んだとしても、一番最後に結果を評価することが出来る機構が欲しかったので作りました。
実装
extension XCTestCase {
typealias DoneStatement = () -> Void
func wait(till num: Int = 1, message: String = __FUNCTION__, _ block: DoneStatement -> DoneStatement) {
self.wait(till: num, message: message, timeout: 10, block)
}
func wait(till num: Int, message: String = __FUNCTION__, timeout: NSTimeInterval, _ block: DoneStatement -> DoneStatement) {
let expectation = self.expectationWithDescription(message)
let queue = dispatch_queue_create("XCTestCase.wait", nil)
var living = num
var completion: (() -> Void)!
let done: DoneStatement = {
dispatch_async(queue) { //シングルキューで必ず順番に処理する
living--
if living == 0 {
completion?()
expectation.fulfill()
}
}
}
completion = block(done)
self.waitForExpectationsWithTimeout(timeout) { (error) -> Void in
completion?()
return
}
}
}
使い方
上記extension
を実装し、以下のように呼び出します。
HogeTests.swift
func test_一つの場合() {
wait { done in
let queue = dispatch_queue_create("hoge", nil)
dispatch_async(queue) {
XCTAssertEqual(1 + 2, 3, "")
done()
}
return {
XCTAssertEqual(1 + 1, 2, "waitの一番最後に呼び出される")
}
}
}
func test_複数の場合() {
wait(till: 2) { done in
var ret = 0
let queue = dispatch_queue_create("hoge", nil)
dispatch_after(when(0.4), queue) {
XCTAssertEqual(1 + 2, 3, "")
done()
}
dispatch_after(when(1), queue) {
XCTAssertEqual(1 + 3, 4, "")
ret = 2
done()
}
return {
XCTAssertEqual(2, ret, "")
XCTAssertEqual(1 + 1, 2, "waitの一番最後に呼び出される")
}
}
}