假设我有这样的
import Alamofire
class NetworkStuff {
func getSomething() async throws -> String {
let params: [String: String] = ["Key": "Value"]
let value = AF.request("https://myapi.com/endpoint", method: .post, parameters: params, encoder: JSONParameterEncoder.default)
.validate()
.responseDecodable([String: String].self).value("KeyIWant")
guard let result = value else {throw MyError.SomeError }
return result
}
}
我该如何编写一个单元测试来验证这个请求是正确的,并且正在解码响应。假设我们将此发送到服务器:
{
"RequestItem": "Value"
}
假设来自服务器的响应看起来像:
{
"ID": "1234",
"KeyIWant": "Value02"
}
我如何编写一个测试来确保我的POST参数的结构符合服务器的预期,然后模拟响应,从而确保我正确地解析它以获得我想要的值?
请记住,您不想在端点测试网络、AlamoFire或服务器。您只想测试您的代码。
要做到这一点,您需要使代码具有可测试性。将getSomething
分解为可测试的子例程——这类东西:
func getSomething() async throws -> String {
let params = self.constructParams()
let value = AF.request("https://myapi.com/endpoint", method: .post, parameters: params, encoder: JSONParameterEncoder.default)
let result = self.processValue(value)
return result
}
现在constructParams
和processValue
是可以通过正常方式进行测试的方法,提供各种输入并检查是否返回预期输出。
我将把答案分成两部分(我想你熟悉XCTest框架或其开源包装器Quick和Nimble,这是我建议用于测试的(:
首先,编写一个测试以确保POST参数的结构正确-我会重建函数并将其作为参数传递给它。然后,我会编写一个负责构建参数的类,并为它编写一个检测套件-确保它正确构建参数,比如
final class ParamBuilder {
func params() -> [String: Any] { ["Key": "Value"] }
}
// Testing
class ParamBuildierTests: XCTestCase {
func testFirst() {
let builder = ParamBuilder()
XCTAssertEqual(builder.params(), ["Key": "Value"])
}
}
第二,模拟和测试响应。我个人建议使用Mockingjay。它的用法非常简单,它可以模拟响应,这样你就可以继续使用与使用Alamofire(URLSession底层(相同的服务NetworkStuff
。它将根据您的偏好截取响应-您可以模拟404响应和不同的有效载荷