You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:08:51