首先,我道歉。我对Angular真的很陌生,我不确定我知道的足够多来问一个好的问题,更不用说提供一些小的工作示例了。
我正尝试在单元测试中使用spyOn,但没有太多运气。
基本上,我的单元测试在组件上调用一个方法,该方法调用一个调用另一个service2的service1。
当我尝试在service1上执行spyOn时,它没有使用我提供的mock值。它调用“真正的”ServiceProvidersHTTPService.getAllUsers并使用AppConfigService而不是MockAppConfigService。
我将从复制我的测试开始。
describe('ProjectAnalystComponent', () => {
let component: ProjectAnalystComponent;
let fixture: ComponentFixture<ProjectAnalystComponent>;
let service: ServiceProvidersHTTPService ;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpClientModule, RouterTestingModule],
declarations: [ ProjectAnalystComponent ],
providers:
[
ServiceProvidersHTTPService,
CurrentCreateProjectService,
NotificationService,
MessageService,
ProjectLeadAnalystHTTPService,
ExceptionService,
{provide: AppConfigService, useClass: MockAppConfigService }
],
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProjectAnalystComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
console.log("######### Did this run");
let service = fixture.debugElement.injector.get(ServiceProvidersHTTPService);
spyOn(service, 'getAllUsers').and.returnValue('{}');
expect(component).toBeTruthy();
});
});发布于 2018-04-11 20:51:44
TL;Dr.模拟您的服务。
解释
在您的测试床中,您提供实际的服务:
providers:[ServiceProvidersHTTPService, ...这意味着您实际上是在调用您的服务的真正方法。
如果你嘲笑你的服务,就像你在那里做的那样:
{provide: AppConfigService, useClass: MockAppConfigService }然后调用在模拟中声明的随机函数。
mocking的另一个好处是,您可以摆脱依赖项的依赖项。
正如您所说,您的服务调用另一个服务:如果您模拟您的第一个服务,则不必将此服务的依赖项添加到您的试验床中。
所以,他们还有一条路要走:
const mock = {
provide: ServiceProvidersHTTPService,
useValue: {
getAllUsers: () => null
}
};现在在你的测试床上:
providers: [mock, ...在useValue中,您必须将实际服务的所有变量和所有函数放入,并将它们模拟为。
在这种情况下,您的函数getAllUsers将简单地返回null,而不是进行HTTP调用。您可以让它返回任何您想要的东西(最好的做法是返回一个与应该返回的值类型相同的值)。
最后一条建议:您的单元测试应该只测试您的实际特性(这里是ProjectAnalystComponent)的函数和方法。您不应该在这里测试您的服务是否调用其他服务:您应该在服务的单元测试中测试该。
如果您有任何问题,请随时提问!
https://stackoverflow.com/questions/49775474
复制相似问题