我如何模拟资源响应?
How can I mock resource responses?
在我的应用程序中,我有一个 class,它封装了一个 Service
并具有 return 资源和请求的方法。在我的测试中,我想模拟 success/failures 请求和资源,而不进行任何真正的网络调用。
因为 Request
是一个协议,所以很容易通过 return 只调用 onSuccess
、onFailure
等的自定义实现
然而,return 和 Resource
的方法并不是那么简单,因为 Resource
是最终的 class 而不是协议。
我想创建一个模拟 Resource
,它在调用 load()
等时不执行任何真正的网络请求,并公开一些方法来伪造一个 success/failure 来触发观察者添加到Resource
.
目前有什么办法吗?
您有多种选择:
存根NetworkingProvider
使用自定义 NetworkingProvider
实现创建您的服务。
// App
var myAppNetworkingProvider: NetworkingProviderConvertible =
URLSessionConfiguration.ephemeral // Siesta default
...
Service(baseURL: "...", networking: myAppNetworkingProvider)
// Tests
myAppNetworkingProvider = NetworkStub()
您的 StubbedNetworkingProvider
可以 return 单个硬编码 URLResponse
,或者匹配 URLRequest
如果您想一次存根多个响应。
这是大多数应用的最佳选择。您可以在 Siesta’s own performance tests 中看到它的示例。它简单、快速,并提供细粒度控制,但仍可让您使用真实的 Siesta 行为进行测试。
存根网络
Siesta 与 OHHTTPStubs, Mockingjay, and 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 { }
这听起来最像您在原始问题中寻找的内容。不过我不是特别推荐:
- 它实施起来最复杂,也是最容易出错的。你会发现准确模仿 Siesta 的所有行为非常困难。相信我:Resource API 一开始看起来很无辜,但如果您尝试以这种方式练习整个应用程序,您会发现自己重新实现了一半的库。
- 它很可能会遗漏问题而不会发现回归。使用 Siesta 的许多危险点都与调用的确切顺序有关:哪些事件发生,以什么顺序发生,立即发生什么与主 运行 循环的后续回合发生什么,什么 observer/owner关系会或不会创建保留周期等。您必须对所有这些事情做出假设,并且您最终将根据您的假设测试您的代码,而不是根据库的真实行为。
简而言之,与其他方法相比,它付出的努力更多,价值更低。这当然不是进行回归测试的有效方法。
就是说,如果您秉承纯粹主义者“不要测试越界”的单元测试理念,那么这就是方法。
我正在编写一个使用 Siesta 的应用程序,我一直在使用 URLMock 模拟 Siesta 发出的网络请求。我对结果很满意(它只是做我想做的,没有太多麻烦),但我相信其他库也能工作。我建议使用网络模拟库,它们具有您可能不会立即想到的功能,例如如果测试发出意外的网络请求,则将其设置为 return 错误。
以下是我如何设置 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)
}
在我的应用程序中,我有一个 class,它封装了一个 Service
并具有 return 资源和请求的方法。在我的测试中,我想模拟 success/failures 请求和资源,而不进行任何真正的网络调用。
因为 Request
是一个协议,所以很容易通过 return 只调用 onSuccess
、onFailure
等的自定义实现
然而,return 和 Resource
的方法并不是那么简单,因为 Resource
是最终的 class 而不是协议。
我想创建一个模拟 Resource
,它在调用 load()
等时不执行任何真正的网络请求,并公开一些方法来伪造一个 success/failure 来触发观察者添加到Resource
.
目前有什么办法吗?
您有多种选择:
存根NetworkingProvider
使用自定义 NetworkingProvider
实现创建您的服务。
// App
var myAppNetworkingProvider: NetworkingProviderConvertible =
URLSessionConfiguration.ephemeral // Siesta default
...
Service(baseURL: "...", networking: myAppNetworkingProvider)
// Tests
myAppNetworkingProvider = NetworkStub()
您的 StubbedNetworkingProvider
可以 return 单个硬编码 URLResponse
,或者匹配 URLRequest
如果您想一次存根多个响应。
这是大多数应用的最佳选择。您可以在 Siesta’s own performance tests 中看到它的示例。它简单、快速,并提供细粒度控制,但仍可让您使用真实的 Siesta 行为进行测试。
存根网络
Siesta 与 OHHTTPStubs, Mockingjay, and 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 { }
这听起来最像您在原始问题中寻找的内容。不过我不是特别推荐:
- 它实施起来最复杂,也是最容易出错的。你会发现准确模仿 Siesta 的所有行为非常困难。相信我:Resource API 一开始看起来很无辜,但如果您尝试以这种方式练习整个应用程序,您会发现自己重新实现了一半的库。
- 它很可能会遗漏问题而不会发现回归。使用 Siesta 的许多危险点都与调用的确切顺序有关:哪些事件发生,以什么顺序发生,立即发生什么与主 运行 循环的后续回合发生什么,什么 observer/owner关系会或不会创建保留周期等。您必须对所有这些事情做出假设,并且您最终将根据您的假设测试您的代码,而不是根据库的真实行为。
简而言之,与其他方法相比,它付出的努力更多,价值更低。这当然不是进行回归测试的有效方法。
就是说,如果您秉承纯粹主义者“不要测试越界”的单元测试理念,那么这就是方法。
我正在编写一个使用 Siesta 的应用程序,我一直在使用 URLMock 模拟 Siesta 发出的网络请求。我对结果很满意(它只是做我想做的,没有太多麻烦),但我相信其他库也能工作。我建议使用网络模拟库,它们具有您可能不会立即想到的功能,例如如果测试发出意外的网络请求,则将其设置为 return 错误。
以下是我如何设置 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)
}