问题描述
这一次,我试图模拟一个服务(执行http调用)以测试组件.
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);
});
}
}
文档(版本2.0.0)说明您应该模拟服务.使用相同的TestBed
配置:
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');
});
});
运行测试时,我得到:
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.
有什么建议吗?谢谢!
推荐答案
是因为
@Component({
providers: [FundingPlanService] <===
})
@Component.providers
的优先级高于所有全局提供程序,因为使用@Component.providers
会使提供程序的作用域仅限于组件.在测试中,Angular在模块范围内创建了模拟服务,在组件范围内创建了原始服务.
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.
为解决此问题,Angular提供了TestBed.overrideComponent
方法,在这里我们可以在组件级别覆盖模板和提供程序之类的东西.
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 },
]
}
})
另请参阅:
这篇关于组件中的模拟服务-模拟被忽略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!