Angular8使用Karma和Jasmine测试报NullInjectorError无api提供者错误
错误原因
NullInjectorError: No provider for api 是因为你的 AppComponent 中依赖注入了名为 api 的自定义服务或注入令牌,测试模块未注册该依赖的提供者,因此运行测试时无法找到对应的实例。你之前添加的 RouterTestingModule、HttpClientModule 是Angular官方提供的通用模块,不包含你自定义的api依赖,因此无法解决问题。
解决方案(二选一即可)
方案1:Mock api 依赖(单元测试推荐)
单元测试不需要依赖真实接口实现,直接mock api 的所有被组件调用的方法即可,修改后的app.component.spec.ts代码如下:
import { TestBed, async } from '@angular/core/testing'; import { AppComponent } from './app.component'; import { RouterTestingModule } from '@angular/router/testing' import { HttpClientModule } from '@angular/common/http'; // 1. 定义mock的api对象,覆盖所有组件中用到的api方法 const mockApi = jasmine.createSpyObj('api', ['你的组件调用的api方法名1', '你的组件调用的api方法名2']); // 如果不需要监控方法调用,也可以直接写普通对象:const mockApi = { 方法名: () => of({}) } describe('AppComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ RouterTestingModule, HttpClientModule ], declarations: [ AppComponent ], // 2. 新增providers配置,注册api的mock实现 providers: [ // 注意:如果你的api是通过InjectionToken定义的,这里provide的值要替换成对应的Token实例 { provide: 'api', useValue: mockApi } ] }).compileComponents(); })); it('should create the app', () => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.componentInstance; expect(app).toBeTruthy(); }); it(`should have as title 'dalivalidb'`, () => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.componentInstance; expect(app.title).toEqual('dalivalidb'); }); it('should render title', () => { const fixture = TestBed.createComponent(AppComponent); fixture.detectChanges(); const compiled = fixture.nativeElement; expect(compiled.querySelector('.content span').textContent).toContain('dalivalidb app is running!'); }); });
方案2:引入真实api提供者(集成测试适用)
如果需要测试真实的接口调用逻辑,直接将你生产环境中注册api提供者的配置同步到测试模块即可:
- 如果
api是在某个自定义模块中声明提供的,直接将该模块添加到测试模块的imports数组中 - 如果
api是直接在AppModule的providers数组中注册的,直接将对应的提供者配置复制到测试模块的providers数组即可
内容的提问来源于stack exchange,提问作者Yoan
相关产品推荐
相关产品推荐

