Angular v12运行ng test报NG0302:管道'myFilter'无法找到错误
Angular v12 ng test 报NG0302管道找不到的问题解答
疑问1:为什么会触发该错误?
你对测试环境的依赖规则存在认知偏差:Angular单元测试的TestBed是完全隔离的运行环境,默认不会继承AppModule里的任何声明、导入、提供者配置。日常ng serve/ng build正常运行,是因为正式运行时会加载完整的AppModule依赖树;但测试环境中每个用例的运行环境都是独立构造的,只要你没有在configureTestingModule中显式配置依赖,Angular就无法识别模板中用到的自定义管道、指令等内容,就会抛出NG0302错误。
疑问2:为什么仅部分组件触发报错?
和你的项目从Angular8升级到12的背景相关,常见的触发场景有3种:
- 未报错的组件测试未触发模板解析:如果测试用例只校验了组件类的逻辑,没有执行
fixture.detectChanges()触发变更检测,Angular不会解析组件模板内容,自然不会检测到模板中使用的管道,也就不会抛出错误。 - 组件所属模块配置差异:如果未报错的组件归属于某个特性模块,且该特性模块在测试时被意外导入到了TestBed配置中;而报错的组件所属模块未被导入,也没有单独声明用到的管道,就会出现部分报错的情况。
- Ivy规则升级带来的差异:Angular9开启Ivy之后,测试环境的依赖隔离规则更加严格,旧版本中可能存在的隐式依赖导入在新版本中失效,部分旧组件的测试可能在升级前就已经添加了依赖配置,新生成的组件测试用例采用默认空配置,就会出现部分报错的情况。
可选用的解决方案
根据你的项目实际情况选择以下任意一种方案即可:
- 单独声明依赖:在报错组件的
*.spec.ts的configureTestingModule配置中,将用到的自定义管道加入declarations数组TestBed.configureTestingModule({ declarations: [ Component2, MyFilterPipe // 替换为你实际用到的管道类 ] }) - 导入公共共享模块:如果你的自定义管道都统一声明并导出在
SharedModule这类公共模块中,直接在测试配置里导入对应公共模块即可,无需单独声明每个管道import { SharedModule } from './shared/shared.module'; TestBed.configureTestingModule({ declarations: [ Component2 ], imports: [ SharedModule ] }) - 配置全局测试依赖:如果大部分测试都需要用到这些公共管道,可以修改全局测试配置文件
test.ts,给所有TestBed默认添加公共依赖,不需要每个spec单独配置import { TestBed } from '@angular/core/testing'; import { SharedModule } from './shared/shared.module'; // 放在initTestEnvironment配置之后执行 TestBed.configureTestingModule({ imports: [ SharedModule ] }).compileComponents(); - 临时跳过模板校验(仅适用于不需要校验模板逻辑的场景,不推荐长期使用):在测试配置中加入
schemas: [ NO_ERRORS_SCHEMA ],Angular会忽略所有不识别的指令、管道、自定义标签import { NO_ERRORS_SCHEMA } from '@angular/core'; TestBed.configureTestingModule({ declarations: [ Component2 ], schemas: [ NO_ERRORS_SCHEMA ] })
内容的提问来源于stack exchange,提问作者cube
相关产品推荐
相关产品推荐

