角度单元测试-未使用模拟服务
我对编码还很陌生,我正在尝试编写自己的应用程序来学习Angular。作为一名优秀的开发人员,我正在为我的代码编写测试,但是我遇到了一个小问题。
我创建了一个使用Angular Material对话框的包装器服务,这是组件中调用包装器服务的方法(以下是一些代码)
这就是我在组件中声明服务的方式
constructor(private modalDialogWrapperService: ModalDialogWrapperService) {}
这是调用服务的方法。
public assignInstrument(instrument: any): void {
this.modalDialogWrapperService.openAssignmentWindow({
product: 'instrument',
type: instrument.type,
serial: instrument.serial,
id: instrument.id
});
}
现在所有这些都可以正常工作,但是我想测试执行assignInstrument时调用modalDialogWrapperService.openAssignmentWindow的组件。这是我的测试文件
describe('InstrumentsPageComponent', () => {
let component: InstrumentsPageComponent;
let fixture: ComponentFixture<InstrumentsPageComponent>;
let modalDialogWrapperServiceSpy: jasmine.SpyObj<ModalDialogWrapperService>;
beforeEach(async(() => {
const mockModalDialogWrapperService =
jasmine.createSpyObj('ModalDialogWrapperService', ['openAssignmentWindow']);
mockModalDialogWrapperService.openAssignmentWindow.and.returnValue(of({}));
TestBed.configureTestingModule({
imports: [MatTableModule, MatPaginatorModule, MatDialogModule, NoopAnimationsModule],
declarations: [InstrumentsPageComponent, ChangeAssignmentComponent],
providers: [{
provide: ModalDialogWrapperService,
useValue: mockModalDialogWrapperService}]
})
.overrideModule(BrowserDynamicTestingModule, { set: { entryComponents: [ChangeAssignmentComponent]}})
.compileComponents();
beforeEach(() => {
fixture = TestBed.createComponent(InstrumentsPageComponent);
modalDialogWrapperServiceSpy = TestBed.get(ModalDialogWrapperService);
component = fixture.componentInstance;
fixture.detectChanges();
});
describe('assignInstrument', () => {
it('should call the Modal Dialog Service', () => {
component.assignInstrument({});
expect(modalDialogWrapperServiceSpy.openAssignmentWindow).toHaveBeenCalledTimes(1);
});
});
现在,这将返回错误“ openAssignmentWindow已被调用一次。被调用0次。”。我注意到,如果我在组件的console.log(this.modalDialogWrapperService);
中写ngOnInit(
,则好像在Jasmine存根中没有替换dalDialogWrapperService。我在做什么错了?
答案 0 :(得分:1)
如果您只想验证是否已调用服务方法,那么您的方法可能会有点过大。您可以仅对实际服务设置间谍,而不必提供执行几乎相同功能的模拟服务。
这是我实施此测试的方式
在您的第一个describe
块中,添加服务引用:
let modalDialogWrapperService: ModalDialogWrapperService;
像通常在模块中一样在beforeEach(async())
中提供它:
providers: [ModalDialogWrapperService]
在您的beforeEach()
中,通过TestBed
获得服务:
modalDialogWrapperService = TestBed.get(ModalDialogWrapperService);
然后您的测试将如下所示:
describe('assignInstrument', () => {
it('should call the Modal Dialog Service', () => {
let spy = spyOn(modalDialogWrapperService, 'openAssignmentWindow').and.returnValue(of({}));
expect(spy).not.toHaveBeenCalled();
component.assignInstrument({});
expect(spy).toHaveBeenCalledTimes(1);
});
});
这需要更少的代码,并且在我看来看起来更加干净。
可以找到Stackblitz here。