Mocking service in a component - mock ignored
It's because of
@Component({
providers: [FundingPlanService] <===
})
The @Component.providers
takes precedence over any global providers, since using the @Component.providers
makes the provider scoped only to the component. In the test, Angular creates the mocked service in the module scope and the original service in the component scope.
To solve this problem, Angular provides the TestBed.overrideComponent
method, where we can override things like templates and providers at the component level.
TestBed.configureTestingModule({
declarations: [FundingPlanComponent]
});
TestBed.overrideComponent(FundingPlanComponent, {
set: {
providers: [
{ provide: FundingPlanService, useClass: FundingPlanServiceMock },
]
}
})
See also:
Related videos on Youtube
![youri](https://i.stack.imgur.com/fSeou.gif?s=256&g=1)
youri
Updated on December 09, 2020Comments
-
youri over 3 years
This time I'm trying to mock a service (that does http calls) to test a component.
@Component({ selector: 'ub-funding-plan', templateUrl: './funding-plan.component.html', styleUrls: ['./funding-plan.component.css'], providers: [FundingPlanService] }) export class FundingPlanComponent implements OnInit { constructor(private fundingPlanService: FundingPlanService) { } ngOnInit() { this.reloadFundingPlans(); } reloadFundingPlans() { this.fundingPlanService.getFundingPlans().subscribe((fundingPlans: FundingPlan[]) => { this.fundingPlans = fundingPlans; }, (error) => { console.log(error); }); } }
The documentation (version 2.0.0) explains that you should mock the service. Using the same
TestBed
configuration:describe('Component: FundingPlan', () => { class FundingPlanServiceMock { getFundingPlans(): Observable<FundingPlan> { return Observable.of(testFundingPlans) } } beforeEach(() => { TestBed.configureTestingModule({ declarations: [FundingPlanComponent], providers: [ { provide: FundingPlanService, useClass: FundingPlanServiceMock }, ] }); fixture = TestBed.createComponent(FundingPlanComponent); component = fixture.componentInstance; }); fit('should display a title', () => { fixture.detectChanges(); expect(titleElement.nativeElement.textContent).toContain('Funding Plans'); }); });
When I run the test, I get:
Error: No provider for AuthHttp!
that is indeedused by the actual service, but not by the mock. So for some reason, the mock is not injected or used.
Any advise? Thanks!
-
rchavarria almost 7 yearsThe provided link would have been extremely useful, but it's kind of broken. Did you mean this one? Override a component's provider
-
amost about 2 yearsPlease note that in order to get an instance of a mocked service (to e.g. spy on its methods) instead of using
TestBed.inject(FundingPlanService)
you'll need to do it like thisfundingPlanService = <any>fixture.debugElement.injector.get(FundingPlanService);