Reputation: 14304
I have the code working in simulator/device and I'm trying to write unit tests for it. However, notify callback is not called in unit tests. Here's is a code for Playgrounds which is also not calling notify callback. I suspect it I may be using the wrong queue, but cannot figure out which one I should use.
import UIKit
class Loader {
func fetch(callback: ((_ result: String)-> Void)) {
callback("SomeString")
}
}
class MyService {
var list: Array<String> = Array()
var loader: Loader = Loader()
var dispatchGroup = DispatchGroup()
func loadList(callback: @escaping (()-> Void)) {
for i in 1...3 {
self.dispatchGroup.enter()
self.loader.fetch(callback: { [weak self] (string) in
self?.list.append(string)
self?.dispatchGroup.leave()
})
}
dispatchGroup.notify(queue: .main) {
callback()
}
}
}
var service = MyService()
service.loadList {
print("Done is not called")
}
UPDATE
Thanks to @paulvs, we need to enable indefinite execution. However, how to enable that for unit tests?
import UIKit
import PlaygroundSupport
class Loader {
func fetch(callback: ((_ result: String)-> Void)) {
callback("SomeString")
}
}
class MyService {
var list: Array<String> = Array()
var loader: Loader = Loader()
var dispatchGroup = DispatchGroup()
func loadList(callback: @escaping (()-> Void)) {
for i in 1...3 {
self.dispatchGroup.enter()
self.loader.fetch(callback: { [weak self] (string) in
self?.list.append(string)
self?.dispatchGroup.leave()
})
}
dispatchGroup.notify(queue: .main) {
callback()
}
}
}
PlaygroundPage.current.needsIndefiniteExecution = true
var service = MyService()
service.loadList {
print("Done is called now!")
}
Upvotes: 3
Views: 2188
Reputation: 14304
Thanks for the idea to @paulvs, and to this post, here's the code needed for unit tests:
let service = MyService()
let expect = expectation(description: "longRunningFunction")
service.loadList {
expect.fulfill()
}
self.waitForExpectations(timeout: 0.5) { error in
XCTAssert(service.isLoaded, "Not loaded")
}
Upvotes: 3