如何测试异步方法结果?

时间:2017-11-01 08:32:29

标签: swift unit-testing

当我们获得表视图数据源时,我们将询问网络请求。它是异步的。我不知道测试结果操作。有一种获得积分的方法。

     func loadPoints() {
        API().retrievePoints{ [weak self](pointsSet, error) in
            DispatchQueue.main.async(execute: {
                // Make sure the call succeeded; return an error if it didn't
                guard error == nil else {
                    self?.showErrorMessage()
                    Device.debugLog(item:"Error loading Points: \(String(describing: error))")
                    return
                }

                self?.pointsSet = pointsSet
                self?.tableView.reloadData()
            })
        }
    }

我知道如果我们想测试retrievePoints方法,我们可以像下面那样进行测试

//points
func testRetrievePoints() {
    let expectation = self.expectation(description: "RetrievePoints")
    API().retrievePoints{ (pointsSet, error) -> Void in
        XCTAssertNil(pointsSet)
        XCTAssertNotNil(error)
        expectation.fulfill()
    }
    waitForExpectations(timeout: 15.0, handler: nil)
}

现在我想测试代码

         self?.pointsSet = pointsSet
         self?.tableView.reloadData()

         self?.showErrorMessage()

现在我只是使用sleep(15)等待该方法。但这是不准确的。 请你帮助我好吗?提前谢谢。

2 个答案:

答案 0 :(得分:0)

就像你说的那样,它是异步的。所以在完成之前需要一些时间。也就是说你需要等到才能成功。 另请注意,它只是超时值。您的所有任务必须在此值内完成。或者它将被视为失败。

答案 1 :(得分:0)

您想测试数据源 - 而不是您的网络服务。 因为你应该嘲笑api电话。

要实现这一点,您可以使用模拟框架。但我宁愿走另一条路:

  1. 创建一个声明API公共接口的协议,让API符合该协议

  2. API作为依赖项传递给数据源。作为init参数或通过属性。传递对象比类更容易,我将retrievePoints更改为实例方法。

  3. 为您的测试编写一个实现协议的APIMock。让retrievePoints'回调返回准备好的点。

  4. 现在点数将立即返回,无需超时。如果您想推迟您的模拟可以使用DispatchQueue.main.asyncAfter来电。