0

我设置了一个 Jasmine spy 来测试当用户单击一个按钮(触发 goBack() 函数)时,它会打开一个对话框组件,或者就测试而言,调用一个东西。这是一个非常简单的测试,我有几乎相同的测试可以工作,但是这个因为某种原因没有。测试的输出说Expected spy open to have been called

带按钮的组件.component.ts

import { MatDialog } from '@angular/material/dialog';

export class ComponentWithAButton {
    constructor(private closeDialog: MatDialog) {}
    // A button triggers the following function
    goBack(): void {
        this.closeDialog.open(CloseDialogComponent);
    }
}

带按钮的组件.component.spec.ts

import { MatDialog } from '@angular/material/dialog';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentWithAButton } from './component-with-a-button.component';

const closeDialogMock = { open: () => {} };

describe('ComponentWithAButton', () => {
    let component: ComponentWithAButton;
    let fixture: ComponentFixture<ComponentWithAButton>;

    beforeEach(async () => {
        await TestBed.configureTestingModule({
            declarations: [ComponentWithAButton],
            providers: [
                {
                    provide: MatDialog,
                    useValue: closeDialogMock,
                }
            ],
        }).compileComponents();
    });

    beforeEach(() => {
        fixture = TestBed.createComponent(ComponentWithAButton);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    describe('goBack', () => {
        it('should call closeDialog.open', () => {
            const closeDialogSpy = spyOn(closeDialogMock, 'open');
            component.goBack();
            expect(closeDialogSpy).toHaveBeenCalled();
        });
    });
});
4

1 回答 1

-1

事实证明,茉莉花不会让你使用两个相同类型的提供者(好吧,理论上你应该能够添加multi: true标志来使用多个相同的提供者,但它对我不起作用,所以这就是我需要做更多的阅读),最后一个将优先。在这个问题中,我简化了我的实际代码以专注于我认为问题所在的位置。我的实际组件代码看起来更像这样(注意两个MatDialogs 而不是一个):

import { MatDialog } from '@angular/material/dialog';
import { CloseDialogComponent } from 'some/direcotry/close-dialog.component';
import { SubmitDialogComponent } from '/other/directory/submit-dialog.component';

export class ComponentWithAButton {
    constructor(private closeDialog: MatDialog, private submitDialog: MatDialog) {}

    goBack(): void {
        this.closeDialog.open(CloseDialogComponent);
    }

    submit(): void {
        this.submitDialog.open(SubmitDialogComponent);
    }
}

为了解决一种类型的多个提供者的问题,我MatDialog将构造函数中的 s 减少为一个,并编写了一个接受通用组件的对话框构建器函数,所以现在组件看起来更像这样:

import { MatDialog } from '@angular/material/dialog';
import { ComponentType } from '@angular/cdk/portal';
import { CloseDialogComponent } from 'some/direcotry/close-dialog.component';
import { SubmitDialogComponent } from '/other/directory/submit-dialog.component';

export class ComponentWithAButton {
    constructor(private dialogConstructor: MatDialog) {}

    goBack(): void {
        this.constructDialog(CloseDialogComponent);
    }

    submit(): void {
        this.constructDialog(SubmitDialogComponent);
    }

    private constructDialog(component: ComponentType<any>) {
        this.dialogConstructor.open(component);
    }
}
于 2021-11-19T18:38:12.103 回答