简体   繁体   English

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

[英]Angular Unit Test - Mocked Service is not being used

Angular Unit Test - Mocked Service is not being used Angular 单元测试 - 未使用模拟服务

I'm pretty new to coding and I am trying to write my own app to learn Angular.我对编码很陌生,我正在尝试编写自己的应用程序来学习 Angular。 As a good developer I am writing tests for my code but I am having a little issue.作为一名优秀的开发人员,我正在为我的代码编写测试,但我遇到了一个小问题。

I have created a wrapper service that uses the Angular Material Dialog, this is the method in my component that calls the wrapper service (here's some code)我创建了一个使用 Angular Material Dialog 的包装服务,这是我的组件中调用包装服务的方法(这是一些代码)

this how I declare the service in my component这就是我在组件中声明服务的方式

constructor(private modalDialogWrapperService: ModalDialogWrapperService) {}

this is method that calls the service.这是调用服务的方法。

public assignInstrument(instrument: any): void {
    this.modalDialogWrapperService.openAssignmentWindow({
        product: 'instrument',
        type: instrument.type,
        serial: instrument.serial,
        id: instrument.id
    });
}

Now all this works fine but I want to test the component that when assignInstrument is executed the modalDialogWrapperService.openAssignmentWindow is called.现在所有这些都工作正常,但我想测试在执行assignInstrument 时调用modalDialogWrapperService.openAssignmentWindow 的组件。 Here is my test file这是我的测试文件

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);
        });
    });

Now this brings back the error "openAssignmentWindow to have been called once. It was called 0 times.".现在这会带回错误“openAssignmentWindow 已被调用一次。它被调用了 0 次。”。 I've noticed that if I write console.log(this.modalDialogWrapperService);我注意到如果我写console.log(this.modalDialogWrapperService); in my component's ngOnInit( ) it looks as if the dalDialogWrapperService does not get replaced in the Jasmine stub.在我的组件的ngOnInit( ) 中,它看起来好像 dalDialogWrapperService 没有在 Jasmine 存根中被替换。 What am I doing wrong?我究竟做错了什么?

Your approach might be a bit of an overkill if you just want to validate if the service method has been called.如果您只想验证服务方法是否已被调用,那么您的方法可能有点矫枉过正。 You could just set up a spy on the actual service instead of providing a mock service that does pretty much the same thing.您可以在实际服务上设置一个间谍,而不是提供一个做几乎相同事情的模拟服务。

Here is how I would implement this test这是我将如何实施此测试

In your first describe block add your a service reference:在您的第一个describe块中添加您的服务引用:

let modalDialogWrapperService: ModalDialogWrapperService;

Provide it as you normally would in a module, but in your beforeEach(async()) :像往常一样在模块中提供它,但在你的beforeEach(async())

providers: [ModalDialogWrapperService]

In your beforeEach() get the service via the TestBed :在您的beforeEach()通过TestBed获取服务:

modalDialogWrapperService = TestBed.get(ModalDialogWrapperService);

And then your test would look like this:然后你的测试看起来像这样:

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);
  });
});

This requires less code and looks a bit cleaner in my opinion.在我看来,这需要更少的代码并且看起来更简洁。

Stackblitz can be found here . Stackblitz 可以在这里找到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM