单元测试柯里化工厂函数应验证其返回函数的配置固化效果而非执行逻辑;通过检查返回值类型、mock外部依赖并断言实际请求参数(如baseUrl、timeout)来确认默认配置是否正确合并,覆盖部分/完全覆盖及浅合并场景。

单元测试中验证柯里化工厂函数的配置生成结果,关键不是“执行它”,而是“检查它返回了什么结构”。因为柯里化函数本身不立即执行业务逻辑,而是返回一个预设参数的新函数——这个新函数的内部闭包状态,就是你要断言的核心。
直接调用并比对返回函数的特征
柯里化后的工厂函数(如 createRequest(defaults))返回的是一个函数。你可以通过以下方式确认它是否正确固化了配置:
- 检查返回值是否为函数:
expect(typeof apiRequest).toBe('function') - 验证该函数是否携带预期的默认配置(需借助闭包探测或行为推断):可调用它传入最小合法参数,再 mock 外部依赖(如
fetch),断言实际发起的请求是否含预期baseUrl、timeout等字段 - 避免试图读取闭包变量(JavaScript 不提供标准 API 访问闭包),转而用“行为即契约”:只要它在后续调用中表现出正确的配置合并逻辑,就说明固化成功
用 mock + 断言副作用来验证配置效果
这是最实用、最可靠的方式。以带默认配置的请求函数为例:
const createRequest = (defaults) => (options) =>
fetch(defaults.baseUrl + options.url, {
...defaults,
...options
});
测试时:
立即学习“Java免费学习笔记(深入)”;
- 用
vi.mock('node:fs')或jest.mock('node:fetch')拦截全局fetch - 创建工厂实例:
const apiRequest = createRequest({ baseUrl: '/api', timeout: 5000 }) - 调用
apiRequest({ url: '/users' }) - 断言
fetch是否被调用,且第一个参数是'/api/users',第二个参数中timeout是否为5000
测试运行时覆盖与浅合并逻辑
真实场景中,用户选项应能覆盖默认值。测试需覆盖“部分覆盖”和“完全覆盖”两种情况:
- 传入
{ url: '/orders', timeout: 8000 }→ 验证最终timeout是8000,而非默认的5000 - 传入
{ url: '/health' }(不传timeout)→ 验证仍使用默认5000 - 若配置含嵌套对象(如
headers),需额外验证是否为浅合并(例如默认{ headers: { 'X-App': 'v1' } }+ 用户传{ headers: { 'Authorization': 'Bearer...' } }应得{ 'Authorization': '...', 'X-App': 'v1' })
对多级柯里化工厂分层断言
对于三级柯里化(如 createClient(global)(module)(action, data)),测试应分阶段验证:
- 第一级返回函数:
const clientWithGlobal = createClient({ baseUrl: 'https://prod.api' })→ 断言其类型与可调用性 - 第二级返回函数:
const tenantClient = clientWithGlobal({ tenantId: 't-123' })→ 可再次 mock 并触发第三级,验证tenantId是否注入到最终请求头或路径中 - 不强求每一级都单独断言闭包内容,重点保障最终调用链的行为符合配置组合预期


















