使用Quick和Nimble在测试中设置认证请求头
嘿,刚好我之前也用Quick/Nimble处理过类似的认证测试场景,给你几个实用的方案:
测试AuthenticationManager认证请求头的几种方法
你的headers属性是基于token计算生成的,所以核心思路就是通过控制token的状态,来验证headers的输出是否符合预期。下面是具体的实现方式:
1. 直接操作单例的token(最简单直接)
因为你的token是public变量,所以可以直接在测试中给单例设置测试用token,测试完成后记得重置状态,避免影响其他测试用例:
import Quick import Nimble @testable import YourApp class AuthenticationManagerSpec: QuickSpec { override func spec() { describe("AuthenticationManager") { describe("headers") { context("when a valid token exists") { beforeEach { // 给单例设置测试用token AuthenticationManager.shared.token = "mock-test-token-789" } afterEach { // 测试完成后重置token,保证测试隔离 AuthenticationManager.shared.token = nil } it("includes Authorization Bearer header and Accept header") { let expectedHeaders = HTTPHeaders([ "Authorization": "Bearer mock-test-token-789", "Accept": "application/json" ]) expect(AuthenticationManager.shared.headers).to(equal(expectedHeaders)) } } context("when no token exists") { beforeEach { AuthenticationManager.shared.token = nil } it("only includes Accept header") { let expectedHeaders = HTTPHeaders([ "Accept": "application/json" ]) expect(AuthenticationManager.shared.headers).to(equal(expectedHeaders)) } } } } } }
2. 用协议抽象+测试实例(更优雅的隔离方式)
如果想避免直接依赖单例的全局状态(毕竟单例容易导致测试间的状态污染),可以给AuthenticationManager定义一个协议,然后在测试中使用独立的实例:
第一步:定义协议并让原类遵循
protocol AuthenticationProvider { var token: String? { get set } var headers: HTTPHeaders { get } } // 让原有的AuthenticationManager遵循协议 class AuthenticationManager: AuthenticationProvider { static let shared: AuthenticationProvider = AuthenticationManager() // 原有的token和headers实现保持不变 public var token: String? public var headers: HTTPHeaders { guard let token = token else { return ["Accept": "application/json"] } return [ "Authorization": "Bearer \(token)", "Accept": "application/json" ] } }
第二步:编写隔离式测试
class AuthenticationManagerSpec: QuickSpec { override func spec() { describe("AuthenticationManager") { // 每次测试都创建一个新的实例,完全隔离状态 var authManager: AuthenticationManager! beforeEach { authManager = AuthenticationManager() } describe("headers") { it("returns correct headers with token") { authManager.token = "isolated-test-token-123" let expectedHeaders = HTTPHeaders([ "Authorization": "Bearer isolated-test-token-123", "Accept": "application/json" ]) expect(authManager.headers).to(equal(expectedHeaders)) } it("returns default headers when token is nil") { authManager.token = nil let expectedHeaders = HTTPHeaders([ "Accept": "application/json" ]) expect(authManager.headers).to(equal(expectedHeaders)) } } } } }
3. 模拟完整登录流程(贴近真实业务场景)
如果你的测试需要模拟真实的登录流程(比如调用login方法后验证headers),可以结合Nimble的异步断言来实现:
context("after successful login") { beforeEach { // 假设login是异步方法,带completion回调 waitUntil { done in AuthenticationManager.shared.login(username: "test_user", password: "test_pass") { success in expect(success).to(beTrue()) done() } } } it("updates headers with the new token") { expect(AuthenticationManager.shared.headers).to(haveKeyWithValue("Authorization", containing: "Bearer ")) expect(AuthenticationManager.shared.headers).to(haveKeyWithValue("Accept", "application/json")) } }
这里用到了Nimble的haveKeyWithValue匹配器,能更灵活地验证HTTPHeaders的内容。
内容的提问来源于stack exchange,提问作者ilikecode
相关产品推荐
相关产品推荐

