角单元测试-未使用模拟服务

时间:2019-03-04 13:24:27

标签: angular unit-testing jasmine

角度单元测试-未使用模拟服务

我对编码还很陌生,我正在尝试编写自己的应用程序来学习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。我在做什么错了?

1 个答案:

答案 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