I'm trying to use the new DispatchGroup
mechanism with an OperationQueue
so that my unit test will wait for completion. After watching the WWDC videos I've only seen how to use groups with async calls from regular dispatches. How do I get the same functionality with Operation Queues?
This is my test without any pauses (and therefore it passes without stopping to test assertion in completion block):
func testAlertOperationPresentsMessage() {
var testSuccess = false
let action: AlertClosure = { action in
testSuccess = true
}
let alert = AlertOperation(title: "Test", message: "Message", context: nil, action: action)
alert.completionBlock = { XCTAssert(testSuccess) }
OperationQueue.main.addOperation(alert)
}
In previous versions of Swift I would've done something like this:
func testAlertOperationPresentsMessage() {
var testSuccess = false
let action: AlertClosure = { action in
testSuccess = true
}
let alert = AlertOperation(title: "Test", message: "Message", context: nil, action: action)
let group = dispatch_group_create()
dispatch_group_enter(group)
alert.completionBlock = { dispatch_group_leave(group) }
OperationQueue.main.addOperation(alert)
dispatch_group_wait(group, FOREVER...) {
XCTAssert(testSuccess)
}
}
In Swift 3, I think I'm meant to do something like this...
func testAlertOperationPresentsMessage() {
var testSuccess = false
let action: AlertClosure = { action in
testSuccess = true
}
let alert = AlertOperation(title: "Test", message: "Message", context: nil, action: action)
let group = DispatchGroup()
OperationQueue.main.async(group: group) {
alert.start()
}
group.notify(queue: DispatchQueue.main) { XCTAssert(testSuccess) }
}
or:
func testAlertOperationPresentsMessage() {
var testSuccess = false
let action: AlertClosure = { action in
testSuccess = true
}
let alert = AlertOperation(title: "Test", message: "Message", context: nil, action: action)
alert.completionBlock = { XCTAssert(testSuccess) }
let queue = OperationQueue()
queue.addOperation(alert)
queue.waitUntilAllOperationsAreFinished()
// OperationQueue.main.addOperation(alert)
}
I use the following type alias:
typealias AlertClosure = ((UIAlertAction) -> Void)?
If needed I can include code for AlertOperation
, but that doesn't seem necessary at this point. Essentially, the AlertOperation
presents a message and then performs the AlertClosure
when USER taps OK button.