Angular单元测试中如何Mock继承类?问题求助
问题分析与解决方案
你遇到的核心问题是:EntityApi直接继承了BaseApi,当TestBed创建EntityApi实例时,它会直接调用真实BaseApi的构造函数,完全绕开你配置的BaseApiStub。TestBed里的{ provide: BaseApi, useClass: BaseApiStub }只在代码通过依赖注入直接请求BaseApi实例时生效,而子类继承父类的场景下,父类构造函数是被子类直接调用的,不走依赖注入流程,所以你的Stub根本没被触发。
下面给你两种可行的修正方案:
方案一:直接Mock EntityApi(最简单直接)
既然组件依赖的是EntityApi,我们直接替换这个服务的实现,完全跳过真实的EntityApi和BaseApi,这是单元测试隔离依赖的常规操作:
步骤1:创建EntityApiStub
export class EntityApiStub { constructor() { console.log("You are on track!!"); } // 可以添加组件需要调用的方法,比如get() get() { return Promise.resolve([]); // 模拟返回数据 } }
步骤2:修改测试配置
在TestBed.configureTestingModule的providers里替换EntityApi:
beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [EntityListComponent], providers: [ // 直接把EntityApi替换为我们的Stub { provide: EntityApi, useClass: EntityApiStub } ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); // 注意:你之前把beforeEach和it写在了async的回调里,这是语法错误!要把它们移出来 beforeEach(() => { fixture = TestBed.createComponent(EntityListComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); }));
这样TestBed会给组件注入EntityApiStub实例,控制台会输出你预期的日志,测试也能正常通过。
方案二:重构依赖方式(适合长期维护)
如果你的项目中有多个类似EntityApi的子类,都需要Mock父类BaseApi,可以重构代码让父类通过依赖注入传入,而不是直接继承:
步骤1:修改业务代码
// BaseApi保持不变 export class BaseApi { constructor(injector: Injector, private endpoint: string) { console.log("Should not be here..."); } } // 把EntityApi改成依赖注入BaseApi,而非继承 @Injectable() export class EntityApi { constructor(private baseApi: BaseApi) {} // 复用BaseApi的方法,比如: get() { return this.baseApi.get(); } }
步骤2:修改测试配置
这时你原来的BaseApiStub配置就会生效了:
beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [EntityListComponent], providers: [ { provide: BaseApi, useClass: BaseApiStub }, EntityApi // 现在EntityApi会依赖注入Stub版本的BaseApi ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); }));
这种方式需要修改业务代码,但能让父类的Mock更灵活,适合复杂场景。
另外提醒你一个语法错误:你之前把内层的beforeEach和it写在了async(() => {})的回调函数里,这会导致测试逻辑无法正常执行,一定要把它们移到async回调外面。
内容的提问来源于stack exchange,提问作者Premkumar
相关产品推荐
相关产品推荐

