AngularJS 1.7自定义过滤器Jest单元测试注入错误排查
解决AngularJS 1.7.x过滤器在Jest中测试的模块注入问题
我帮你梳理下问题所在,以及如何在不加载整个应用的前提下正确配置测试环境:
核心问题分析
你遇到的模块注入错误,主要是因为过滤器依赖的app.module模块未在测试环境中提前声明,同时加载顺序和注入方式也有需要调整的地方。AngularJS要求在注册过滤器/组件之前,对应的模块必须已经存在,而你不想加载整个应用,所以我们可以手动创建一个空的app.module模块来满足依赖。
修正后的测试代码
下面是可以正常运行的测试文件写法,每一步都有注释说明:
// 1. 先加载Angular核心库,确保全局有angular对象 const angular = require('angular'); // 2. 再加载Angular Mocks,它会依赖已加载的angular对象来扩展测试API require('angular-mocks'); // 3. 关键步骤:手动创建过滤器依赖的`app.module`空模块 // 不需要加载整个应用的模块代码,只需要声明这个模块即可 angular.module('app.module', []); // 4. 现在加载你的过滤器文件,它会注册到已存在的`app.module`模块上 require('./takeTheThing.filter.js'); describe('takeTheThing Filter', () => { let takeTheThingFilter; beforeEach(() => { // 加载我们的模块到测试环境 angular.mock.module('app.module'); // 5. 通过Angular的$filter服务获取过滤器实例(标准方式) inject(($filter) => { takeTheThingFilter = $filter('takeTheThing'); }); }); it('should append " thing!" to any input value', () => { // 测试字符串输入 expect(takeTheThingFilter('test')).toBe('test thing!'); // 测试数字输入(会被自动转为字符串) expect(takeTheThingFilter(1)).toBe('1 thing!'); // 测试空输入 expect(takeTheThingFilter('')).toBe(' thing!'); }); });
关键调整点说明
- 加载顺序:必须先加载Angular,再加载Angular Mocks。因为
angular-mocks是基于全局angular对象扩展的,顺序反了会导致测试API(比如angular.mock.module、inject)无法使用。 - 提前声明模块:手动创建
app.module空模块,避免了加载整个应用的代码,同时满足过滤器注册时的模块依赖要求。 - 正确获取过滤器:使用
$filter服务来获取过滤器实例是AngularJS测试中的标准做法,比直接注入过滤器名称(比如takeTheThingFilter)更可靠,尤其是在复杂测试场景下。
常见错误排查
- 如果仍然报错"Module 'app.module' is not available":检查是否在加载过滤器之前声明了模块,顺序绝对不能反。
- 如果
inject函数未定义:确认Angular Mocks已经正确加载,且加载顺序在Angular之后。 - 如果过滤器未找到:检查过滤器文件中的模块名称是否和测试中声明的
app.module完全一致,大小写敏感。
内容的提问来源于stack exchange,提问作者Mattygabe
相关产品推荐
相关产品推荐

