在我的应用程序中,我有一个封装了Service
的类,并且具有返回资源和请求的方法。在我的测试中,我想模拟请求和资源的成功/失败而不进行任何真正的网络调用。由于Request
是一个协议,通过返回一个只调用的自定义实现很容易做到这一点onSuccess
,onFailure
等。
但是,返回Resource
的方法并不那么简单,因为Resource
是最终类而不是协议。
我想创建一个模拟{{1调用Resource
等时没有做任何真实的网络请求,并暴露某种方式伪造成功/失败,触发添加到load()
的观察者。
目前有没有办法做到这一点?
答案 0 :(得分:5)
您有几种选择:
NetworkingProvider
使用自定义NetworkingProvider
实施创建您的服务。
// App
var myAppNetworkingProvider: NetworkingProviderConvertible =
URLSessionConfiguration.ephemeral // Siesta default
...
Service(baseURL: "...", networking: myAppNetworkingProvider)
// Tests
myAppNetworkingProvider = NetworkStub()
如果您希望一次存根多个回复,则StubbedNetworkingProvider
可以返回单个硬编码的URLResponse
,或匹配URLRequest
。
这是大多数应用的最佳选择。你可以在Siesta’s own performance tests中看到它的一个例子。它简单,快速,并且提供了细粒度的控制,但仍然允许您使用逼真的Siesta行为进行测试。
Siesta使用网络存根库,例如OHHTTPStubs,Mockingjay和Nocilla。 (Siesta本身使用Nocilla进行内部回归测试,虽然该库具有内部竞争条件,但在撰写本文时并未得到特别好的维护,所以我不能全心全意地推荐它。)
对网络本身进行存储可以测试应用与底层网络API的完全交互。这种方法可能最适合全面集成测试,特别是如果您想要记录和重放来自真实API的响应。
由于Swift支持retroactive modeling,Resource
不需要(或实现)可测试协议。您可以创建自己的一个:
protocol ResourceProtocol {
// Resource methods your app uses
}
// No new methods; just adding conformance
extension Resource: ResourceProtocol { }
这听起来最像您在原始问题中寻找的内容。但是,我不特别推荐它:
简而言之,与其他方法相比,较低价值的努力更高。这肯定不是进行回归测试的有效方法。
那就是说,如果你坚持纯粹主义者“不要超越界限”的单元测试理念,那么就是这样做的方法。
答案 1 :(得分:1)
我正在编写一个使用Siesta的应用程序,我一直在使用URLMock来模拟Siesta所做的网络请求。我对结果感到满意(它只是做了我想要的而不用大惊小怪),但我确信其他库也能正常工作。我建议使用网络模拟库,它们具有您可能不会立即想到的功能,例如将其设置为在测试发出意外网络请求时返回错误。
以下是我如何设置URLMock以使用Siesta:
override class func setUp() {
super.setUp()
UMKMockURLProtocol.enable()
UMKMockURLProtocol.setVerificationEnabled(true)
}
override class func tearDown() {
UMKMockURLProtocol.setVerificationEnabled(false)
UMKMockURLProtocol.disable()
super.tearDown()
}
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
UMKMockURLProtocol.reset()
let testConfig = URLSessionConfiguration.ephemeral
testConfig.protocolClasses = [UMKMockURLProtocol.self]
service = Service(baseURL: expectedV2Host, useDefaultTransformers: true, networking: testConfig)
}