Angular Jest测试依赖DatePipe的管道时触发NG0203注入上下文错误
为什么直接new TimestampDatePipe()会报错?
Angular的inject()函数有严格的调用上下文要求:它必须在Angular提供的注入上下文内执行,比如框架自动创建类实例时的构造函数、工厂函数、字段初始化器等场景。
你写的TimestampDatePipe用字段初始化器调用inject(DatePipe),这种写法本身没问题,但前提是这个管道实例必须由Angular的注入系统来创建(比如在组件的providers里声明,或者用inject(TimestampDatePipe)获取)。当你在测试里手动用new创建实例时,Angular的注入系统完全没参与这个过程,此时执行字段里的inject()就没有对应的注入上下文,自然触发NG0203错误。
为什么构造函数传参的方式能解决问题?
当你通过TestBed.inject(DatePipe)获取DatePipe实例时,TestBed已经帮你搭建好了合法的注入上下文,拿到的DatePipe是Angular注入系统管理的有效实例。把这个实例传给自定义管道的构造函数后,自定义管道不需要再调用inject()来获取依赖——而是通过显式传参拿到依赖,整个过程不依赖Angular的注入上下文自动注入,所以不会触发错误。
这是不是Angular的Bug?
不是。Angular的设计就是如此:inject()只能在框架控制的注入上下文里使用,手动new实例不属于框架管理的场景,这种情况下的inject()调用本来就不被支持。你的字段初始化器写法在正常业务代码里(由Angular创建实例)是有效的,但测试里手动实例化的场景需要用构造函数注入或者通过TestBed获取管道实例,这是符合Angular注入机制的预期行为。
内容的提问来源于stack exchange,提问作者Jake Smith

