如何在Awilix中为部分测试场景mock已注册的resolver
Awilix局部mock resolver实现方案
你当前的实现存在两个核心问题:
- 直接修改全局单例容器的注册项,所有导入该容器的模块都会受影响,无法实现部分测试文件mock的需求
- 测试代码中注册的是
heavyTaskresolver,和你要mock的目标network不匹配,会导致mock不生效
解决方案
Awilix支持创建嵌套作用域容器,作用域内的注册项仅对当前作用域生效,不会修改父级全局容器的配置,刚好匹配你分文件mock的需求。作用域容器resolve时会优先使用自身注册的resolver,未注册的项会自动继承全局容器的原始实现。
b.test.js完整实现示例
const awilix = require('awilix'); const baseContainer = require('../container'); // 仅当前测试文件生效的mock配置 describe('b测试集合', () => { let testContainer; // 若整个测试文件共用同一个mock,可直接在这里创建一次作用域 beforeEach(() => { // 基于全局原始容器创建独立测试作用域 testContainer = baseContainer.createScope(); // 仅在当前作用域内注册mock的network实现 const mockNetwork = jest.fn().mockResolvedValue('mock返回值'); testContainer.register({ network: awilix.asValue(mockNetwork) }); }); it('测试网络请求mock生效', async () => { // 从测试作用域resolve,拿到的是mock实例,耗时仅几毫秒 const result = await testContainer.resolve('network')(); expect(result).toBe('mock返回值'); }); });
其他测试文件处理
你不需要对a.test.js做任何修改,直接导入原始全局容器使用即可,拿到的是真实的network实现,完全不受b.test.js的mock影响。
注意事项
- 如果你的业务代码是直接导入全局容器调用,建议改造为支持传入容器参数,测试时传入当前作用域容器即可,无需修改业务逻辑。
- 用
beforeEach每个用例新建作用域可以避免同文件内测试用例的mock互相污染,若全文件共用一个mock可以把作用域创建逻辑提到describe外层。
内容的提问来源于stack exchange,提问作者yang
相关产品推荐
相关产品推荐

