iOS中的真实场景单元测试

在敏捷开发环境中,编写单元测试和测试驱动的开发是团队和开发人员最后考虑的事情。

编写单元测试浪费时间,维护麻烦并且会污染生产代码是一个神话。 相反,它使您可以遵循最佳实践,例如依赖项注入,松散耦合的代码,编写自Swift发行以来受到广泛认可的协议。

单元测试对于避免大型团队的项目中的错误非常有帮助,因为新的开发人员加入团队可以进行一些更改,这些更改可能会使某些测试用例和方案失败,因此,如果编写了测试用例,则可以很早地发现它。 它还有助于在编写逻辑或函数时考虑所有可能出现的情况。

单元测试的网络示例:

如果您的测试目标(SUT,被测系统)以某种方式与现实世界相关,例如网络和CoreData,则编写测试代码会更加复杂。 基本上,我们不希望我们的测试代码依赖于现实世界中的事物。 SUT不应依赖于其他复杂系统,因此我们能够更快,时间不变和环境不变地对其进行测试。

此外,重要的是我们的测试代码不要“污染”生产环境。 “污染”是什么意思? 这意味着我们的测试代码将一些测试内容写入数据库,将一些测试数据提交至生产服务器,等等。这就是存在依赖项注入的原因。

给定一个应该在生产环境中通过Internet执行的类。 Internet部分称为该类的依赖项。 如上所述,当我们运行测试时,该类的Internet部分必须能够用模拟或伪造环境代替。 换句话说,该类的依赖关系必须是“可注入的”。

依赖注入使我们的系统更加灵活。 我们可以在生产代码中“注入”真实的网络环境。 同时,我们还可以“注入”模拟网络环境来运行测试代码,而无需访问互联网。

为URLSession创建协议,以便可以将模拟对象注入到HttpClient中。

协议1:URLSessionProtocol提供dataTask api。

协议2:URLSessionDataTaskProtocol提供恢复API。

因此,如您在上面的屏幕截图中所见,测试用例已失败。 XCTAssertNotNil的执行无需等待get API的结果。

幸运的是,我们有XCTest Expectations可以测试异步代码。

该机制允许您指定一个或多个“期望”,这些期望将由于测试中的操作而异步发生 。 一旦设置了所有期望值,就会调用“等待” API,该API将阻止后续测试代码的执行,直到满足所有期望条件或发生超时为止。

运作方式:

  1. 设置一个“期望”,告诉Xcode它应该开始等待。
  2. 当我们的异步代码返回时,我们通知测试运行器一切正常,不再需要等待。
  3. 让Xcode知道失败之前应该等待多长时间。

因此,通过定义期望并在接收到数据时调用满载api(),并通过调用API waitForExpectations并设置计时器,直到Xcode必须等待期望完成,才使Xcode在XCTAssert调用之前等待。