【问题标题】:Jasmine spy never getting called茉莉花间谍永远不会被召唤
【发布时间】:2021-11-18 20:14:27
【问题描述】:

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

component-with-a-button.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-with-a-button.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();
        });
    });
});

【问题讨论】:

  • 确保从 .spec 文件的正确路径导入 MatDialog
  • @Stavm 哦,它在里面。我也会用导入来更新帖子。为了简单起见,我只是假设这些。
  • 对我来说,您的代码似乎 100% 有效并且应该可以工作。您可以将 MatDialog 更改为其他服务,任何服务,看看是否有效?我当然忽略了你 beforeEach 中的 asunc 错字
  • @Stavm 看,这也是我不明白的。它看起来很好,但我已经花了一整天的时间。就像我说的,我什至有非常相似的测试(不同的文件/组件)通过就好了。我尝试将 MatDialog 换成其他服务,但仍然没有通过。
  • 奇怪,你能立即返回一个值并重试吗? spyOn(closeDialogMock, 'open').and.returnValue({})

标签: angular jasmine spyon


【解决方案1】:

事实证明,jasmine 不允许您使用相同类型的两个提供程序(好吧,理论上您应该能够添加 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);
    }
}

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 2014-03-18
    • 1970-01-01
    相关资源
    最近更新 更多