我如何模拟资源响应?

use*_*425 4 siesta-swift

在我的应用程序中,我有一个封装a的类,Service并具有返回资源和请求的方法.在我的测试中,我想模拟请求和资源的成功/失败,而不进行任何真正的网络调用.
既然Request是协议,很容易通过返回一个自定义实现,只是要求要做到这一点onSuccess,onFailure等等.

但是,返回a的方法并不那么简单Resource,因为Resource它是最终类而不是协议.
我想创建一个模拟Resource,在load()调用etc 时不会做任何真正的网络请求,并暴露某种方式伪造成功/失败,触发观察者添加到Resource.

目前有没有办法做到这一点?

Pau*_*ell 5

你有几个选择:

把它弄得一团糟 NetworkingProvider

使用自定义NetworkingProvider实现创建服务.

// App

var myAppNetworkingProvider: NetworkingProviderConvertible =
    URLSessionConfiguration.ephemeral  // Siesta default
...
Service(baseURL: "...", networking: myAppNetworkingProvider)

// Tests

myAppNetworkingProvider = NetworkStub()
Run Code Online (Sandbox Code Playgroud)

StubbedNetworkingProvider可以返回单个硬编码URLResponse,或者URLRequest如果您想一次存根多个响应,则匹配.

这是大多数应用程序的最佳选择.你可以在Siesta自己的性能测试中看到它的一个例子.它简单,快速,并提供细粒度控制,但仍然允许您使用逼真的Siesta行为进行测试.

存根网络

Siesta使用网络存根库,如OHHTTPStubs,MockingjayNocilla.(Siesta本身使用Nocilla进行内部回归测试,虽然图书馆有内部竞争条件,但在撰写本文时并未得到特别好的维护,所以我不能全心全意地推荐它.)

对网络本身进行存储可以测试应用与底层网络API的完全交互.这种方法可能最适合全面集成测试,特别是如果您想要记录和重放来自真实API的响应.

自定义资源协议

因为Swift支持追溯建模,Resource所以不需要(或实现)可测试的协议.您可以创建自己的一个:

protocol ResourceProtocol {
  // Resource methods your app uses
}

// No new methods; just adding conformance
extension Resource: ResourceProtocol { }
Run Code Online (Sandbox Code Playgroud)

这听起来最像您在原始问题中寻找的内容.但是,我不特别推荐它:

  • 这是最复杂的实施 - 而且最容易出错.您会发现准确模仿Siesta的所有行为都会非常困难.相信我:资源API起初看起来很无辜,但如果你尝试以这种方式运用整个应用程序,你会发现自己重新实现了一半的库.
  • 它可能会错过问题,而不会发现回归.使用Siesta的许多危险点都与确切的调用顺序有关:哪些事件发生以及以什么顺序发生,在主运行循环的后续转弯中发生什么,观察者/所有者关系做什么或不做什么创建保留周期等等.您必须对所有这些事情做出假设,并且最终会根据您的假设测试您的代码 - 而不是针对图书馆的真实行为.

简而言之,与其他方法相比,它的价值更低.这当然不是进行回归测试的有效方法.

也就是说,如果你坚持纯粹主义者"不要超越界限"的单元测试理念,那么这就是做到这一点的方法.