首先,我道歉。我是Angular的新手,我不确定我是否足够提出一个好的问题,更不用说提供一些小的工作实例了。
我正在尝试在单元测试中使用spyOn,但没有太多运气。
基本上,我的单元测试调用一个调用service1的组件的方法,该方法调用另一个service2。
当我尝试在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();
});
});
答案 0 :(得分:0)
TL; DR 模拟您的服务。
在您的测试平台中,您提供实际服务:
providers:[ServiceProvidersHTTPService, ...
这意味着您实际上调用服务的真实方法。
如果你嘲笑你的服务,就像你在那里做的那样:
{provide: AppConfigService, useClass: MockAppConfigService }
然后你调用你在模拟中声明的随机函数。
模拟的另一个优点是,您可以摆脱依赖项的依赖关系。
正如您所说,您的服务会调用另一项服务:如果您嘲笑您的第一项服务,您不必将此服务的相关性添加到您的测试平台。
所以,他们走了:
const mock = {
provide: ServiceProvidersHTTPService,
useValue: {
getAllUsers: () => null
}
};
现在在您的测试平台中:
providers: [mock, ...
在useValue
中,您必须添加实际服务的所有变量和所有功能,并模拟它们。
在这种情况下,您的函数getAllUsers
将返回null,而不是进行HTTP调用。你可以让它返回你想要的任何东西(好的做法是返回一个与应该返回的值相同的值)。
最后一条建议:您的单元测试应仅测试实际功能的功能和方法(此处为ProjectAnalystComponent
)。您不应该测试您的服务是否在此处调用其他服务:您应该在服务的单元测试中测试 。
如果您有任何疑问,请随时提出!