肖申克
"我想这归结为一种简单的选择,真的。要么忙着测试,要么忙着哭泣。"《肖申克的救赎》
正如在WWDC2018的测试技巧与窍门中所见,使用URLProtocol
子类来模拟单元测试中的网络调用响应是一种非常好的方法,但是设置起来可能很费力。肖申克的目标是将模拟网络响应变成一条指令。
它做两件事:创建一种匹配网络请求的方式,并指定如果匹配成功则返回何种类型的响应。
安装
Carthage
在您的Cartfile
中,使用
github "atetlaw/shawshank"
肖申克只需要添加到您的单元测试目标,而不是应用的主目标。记住添加Carthage运行脚本阶段到测试目标,以及将Shawshank.framework
添加到您的链接库
阶段(只需点击+
按钮,然后选择Carthage/Build
文件夹中的Shawshank.framework
文件即可。)
Cocoapods
将pod 'Shawshank'
添加到您的Podfile
,但仅限于测试目标,如下所示
target 'MyAppTests' do
pod 'Shawshank'
end
其中MyAppTests
是您的应用的单元测试目标名称。然后运行pod install
。
API 示例
Swift
// Match any requests to `http:www.example.com` and return the HTTP status: Not Permitted
Shawshank.take(matching: .scheme("http") && .host("www.example.com")).httpStatus(.notPermitted)
let json = Bundle(for: ShankPublicAPITests.self).json(named: "test")
Shawshank.take(matching: .scheme("http") && .host("www.example.com")).fixture(json)
Shawshank.take { (components: URLComponents) in
return components.host == "www.example.com" && components.port == 82
}.fixture(JSONDataFixture(["test":"json"]))
单元测试示例
func testShawshankMatchingDataTaskRespondingWithJSONDataFixture() {
let testRequest = URLRequest(url: URL(string: "http://www.example.com")!)
Shawshank.take(matching: .scheme("http") && .host("www.example.com")).fixture(JSONDataFixture(["test":"json"]))
let expect = expectation(description: "response successful")
URLSession.shared.dataTask(with: testRequest) { (data, response, error) -> Void in
guard let httpResponse = response as? HTTPURLResponse else { return }
XCTAssertNil(error)
XCTAssertEqual(httpResponse.statusCode, 200)
XCTAssertNotNil(data)
guard let data = data else { XCTFail(); return }
guard let json = try? JSONSerialization.jsonObject(with: data, options:[]) as? Dictionary<String, String> else { XCTFail(); return }
XCTAssertEqual(json?["test"], "json")
expect.fulfill()
}.resume()
waitForExpectations(timeout: 1, handler: nil)
}
致谢
- 原文:[https://nshipster.com/nsurlprotocol/](https://nshipster.com/nsurlprotocol/)
- https://www.raywenderlich.com/59982/nsurlprotocol-tutorial
- http://swiftandpainless.com/an-easy-way-to-stub-nsurlsession/