【问题标题】:Angular Unit Test - Mocked Service is not being usedAngular 单元测试 - 未使用模拟服务
【发布时间】:2019-03-04 13:24:27
【问题描述】:

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

我对编码很陌生,我正在尝试编写自己的应用程序来学习 Angular。作为一名优秀的开发人员,我正在为我的代码编写测试,但我遇到了一个小问题。

我创建了一个使用 Angular Material Dialog 的包装服务,这是我的组件中调用包装服务的方法(这里有一些代码)

这是我在组件中声明服务的方式

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 次。”。我注意到,如果我在组件的 ngOnInit( 中写 console.log(this.modalDialogWrapperService);),看起来好像 dalDialogWrapperService 没有在 Jasmine 存根中被替换。我做错了什么?

【问题讨论】:

  • 您是否在规范文件中的提供程序中包含了 modalDialogWrapperService?
  • 我只使用了以下:提供者:[{provide: ModalDialogWrapperService, useValue: mockModalDialogWrapperService}]
  • 尝试包括可能直接/间接引用的所有服务也尝试包括:{提供:APP_BASE_HREF,useValue:'/'}

标签: angular unit-testing jasmine


【解决方案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.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 2020-04-19
    • 2021-09-18
    • 2019-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多