为什么不在Playground和单元测试中调用GCD调度组通知

时间:2016-11-28 16:36:57

标签: ios swift grand-central-dispatch

我有代码在模拟器/设备中工作,我试图为它编写单元测试。但是,在单元测试中不会调用通知回调。这里是Playgrounds的代码,它也没有调用notify回调。我怀疑它可能使用了错误的队列,但无法确定我应该使用哪一个。

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")
}

更新

感谢@paulvs,我们需要启用无限期执行。但是,如何为单元测试启用它?

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!")
}

1 个答案:

答案 0 :(得分:1)

感谢@paulvs以及post的想法,这是单元测试所需的代码:

let service = MyService()

let expect = expectation(description: "longRunningFunction")

service.loadList {

    expect.fulfill()
}

self.waitForExpectations(timeout: 0.5) { error in

    XCTAssert(service.isLoaded, "Not loaded")
}