是否可以模拟从 Swift 包导入的函数?

发布于 2025-01-12 00:13:12 字数 1357 浏览 0 评论 0原文

我编写了一个名为 JwtApiClient 的简单 Swift 包,它提供了一些辅助函数 用于向受 JWToken 保护的 API 发出 HTTP 请求,并将数据传输为 JSON。

我正在另一个包中使用其中一个函数 (postJsonDictionary):

import Foundation
import JwtApiClient

public func requestToken<T: Decodable>(
  _ username: String,
  _ password: String
) async throws -> T {
  let endpoint = "/users/login" // in the actual code this is an instance of URLComponents
                                // not String but it's irrelevant here
  let credentials = [
    "email": username,
    "password": password
  ]

  // I'd like to be able to mock this call
  return try await postJsonDictionary(endpoint!, credentials)
}

我只是想知道是否可以在单元测试中模拟 postJsonDictionary 以避免发出底层网络请求并能够断言传递给它的参数。

我尝试欺骗我的单元测试,让其相信该函数是全局函数,但它不起作用:

extension NSObject {
  public func postJsonDictionary<T: Decodable>(_ url: URL!, _ dictionary: [String: Any]) async throws -> T {
    try await Task.sleep(nanoseconds: 2 * 1_000_000_000)
    
    let fakeTokenResponse: TokenResponse = TokenResponse(token: "fake-token")
    
    return fakeTokenResponse as! T
  }
}

// XCTestCase below

I have written a simple Swift package called JwtApiClient that provides a few helper functions for making HTTP requests to JWToken-protected APIs that transfer data as JSON.

I am consuming one of these functions (postJsonDictionary) in another package:

import Foundation
import JwtApiClient

public func requestToken<T: Decodable>(
  _ username: String,
  _ password: String
) async throws -> T {
  let endpoint = "/users/login" // in the actual code this is an instance of URLComponents
                                // not String but it's irrelevant here
  let credentials = [
    "email": username,
    "password": password
  ]

  // I'd like to be able to mock this call
  return try await postJsonDictionary(endpoint!, credentials)
}

I was just wondering if it is possible to mock postJsonDictionary in a unit test to avoid making an underlying network request and to be able to assert on the parameters passed to it.

I have tried tricking my unit test into believing the function is a global but it doesn't work:

extension NSObject {
  public func postJsonDictionary<T: Decodable>(_ url: URL!, _ dictionary: [String: Any]) async throws -> T {
    try await Task.sleep(nanoseconds: 2 * 1_000_000_000)
    
    let fakeTokenResponse: TokenResponse = TokenResponse(token: "fake-token")
    
    return fakeTokenResponse as! T
  }
}

// XCTestCase below

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文