简体   繁体   English

Swift 5.5 等待异步 Mocking 和单元测试 - Alamofire

[英]Swift 5.5 Await Async Mocking and Unit Tests - Alamofire

Lets say I have something like this可以说我有这样的东西

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
    }
}

How would I go about writing a unit test to validate that this request is right and that im decoding the response.我将如何 go 关于编写单元测试以验证此请求是否正确以及即时解码响应。 Lets say we send this to the server:假设我们将其发送到服务器:

{
"RequestItem": "Value"
}

Lets say the response from the server looks like:假设来自服务器的响应如下所示:

{
  "ID": "1234",
  "KeyIWant": "Value02"
}

How could I write a test to ensure my POST parameters were structured correctly as the server expects and then mock a response so that I ensure im parsing this correctly to get the value I want?我如何编写测试以确保我的 POST 参数按照服务器的预期正确构造,然后模拟响应以确保我正确解析它以获得我想要的值?

Keep in mind that you do not want to test the.network or AlamoFire or the server at the endpoint.请记住,您不想在端点处测试 .network 或 AlamoFire 或服务器。 You want to test only your code.您只想测试您的代码。

To do that, you need to make your code testable.为此,您需要使代码可测试。 Break out getSomething into subroutines that are testable — this sort of thing: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
}

Now constructParams and processValue are methods that you can test by normal means, providing various inputs and checking to see that you get back the expected outputs.现在constructParamsprocessValue是您可以通过正常方式测试的方法,提供各种输入并检查您是否得到预期的输出。

I will break the answer into two parts (I assume you are familiar with XCTest framework or its open-source wrappers, Quick and Nimble, those are my recommendation to be used for testing):我会将答案分为两部分(我假设您熟悉 XCTest 框架或其开源包装器 Quick 和 Nimble,这些是我推荐用于测试的):

First, writing a test to make sure the POST parameters are structured correctly - I would reconstruct the function and pass them as an argument to it.首先,编写测试以确保 POST 参数的结构正确 - 我将重构 function 并将它们作为参数传递给它。 Then I would write a class that is in charge of building the parameters and write a testing suite for it - making sure it builds the parameters correctly, something like然后我会写一个 class 负责构建参数并为它编写一个测试套件 - 确保它正确构建参数,比如

final class ParamBuilder {
  func params() -> [String: Any] { ["Key": "Value"] }
}

// Testing
class ParamBuildierTests: XCTestCase {

  func testFirst() {
      let builder = ParamBuilder()
       XCTAssertEqual(builder.params(), ["Key": "Value"])
  }
}

Second, mock and test response.第二,模拟和测试响应。 I personally recommend using Mockingjay Its usage is pretty straightforward, and it can mock response such that you can keep using the same service NetworkStuff which is using Alamofire (URLSession underlying).我个人推荐使用Mockingjay它的用法非常简单,它可以模拟响应,这样你就可以继续使用使用 Alamofire(底层 URLSession)的相同服务NetworkStuff It will stub the response according to your preference - you can mock 404 response and different payloads它会根据您的喜好存根响应 - 您可以模拟 404 响应和不同的有效负载

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM