首页 > 解决方案 > 单元测试:响应自定义模式弹出窗口

问题描述

我有一个角度的单元测试。我需要测试保存按钮的功能。因此,当用户单击保存按钮时,会出现一个带有 save 和 cancel 的弹出窗口。所以我希望自动选择保存并执行下一行代码。

beforeEach(async () => {

    fixture = TestBed.createComponent(component);
    component = fixture.componentInstance;
    fixture.detectChanges();
    component.isPrivate = true;
    component.qtsval= 7.0;
    component.changeval= "";
    await component.save();
    //let ConfirmationDialogService = fixture.debugElement.injector.get(ConfirmationDialogComponent);
    spyOn(window,'confirm').and.returnValue(true);
    var displayValuationChangeDriverWarning = component.displayValuationChangeDriverWarning;
    expect(displayValuationChangeDriverWarning).toBeTruthy();
    component.isPrivate = true;
    component.qtsval= 4.0;
  });

我使用了“spyOn(window,'confirm').and.returnValue(true);” 但它没有帮助。请建议我如何解决这个问题

我有这样的弹出窗口:

this.confirmationDialogService
      .confirm(
        this._messageService.areYouSure,
        this._messageService.wouldYouSave,
        this._messageService.save,
        this._messageService.cancel,
        true,
        false
      )
      .then(async confirmed => {});

标签: typescriptangular8

解决方案


好的,我有一些正在工作的东西可供您查看,本质上该方法是将演示测试与业务逻辑分开,我测试了组件/提供者之间的合同以确保在内部调用正确的方法。

这在所有相关组件中重复,这只是测试按钮背后的逻辑。

在 e2e 中,我已经测试以确保模态显示和按钮存在,诚然,您还希望确保模态消失并且按钮也消失并且不再启用,但我确定你不是在这里寻找一个完整的例子。

这是关注点分离,使逻辑远离您的 UI。正如我在上面的评论中提到的,我个人会选择仅对我的逻辑使用单元测试,并在 UI 组件上进行 e2e 测试(确保如果你点击一个按钮,它将从服务或你的意图中检索是)。

无论如何,足够的谈话,更多的代码。我将为那些发现自己与 OP 处于相似位置的人发布一些示例。Github 链接在底部。

单元测试看起来类似于:

  it('.reject() should call activeModal with false', async () => {
    spyOn(activeModal, 'close').and.returnValue(null);

    expect(component.decline()).toBeUndefined();

    expect(activeModal.close).toHaveBeenCalledTimes(1);
    expect(activeModal.close).toHaveBeenCalledWith(false);
  });

和:

  it('should return the correct result of a Modal (object is correct, calls internal modal)', async () => {
    const mock = {
      componentInstance: {
        title: 'Are you sure?',
        message: 'Are you actually sure though?',
        btnOkText: 'OK',
        btnCancelText: 'Cancel',
      },
      result: true,
    };

    spyOn(modal, 'open').and.returnValue(mock as any);

    const result = await service.confirm(
      mock.componentInstance.title,
      mock.componentInstance.message
    );

    expect(result).toBe(mock.result);

    expect(modal.open).toHaveBeenCalledTimes(1);
    expect(modal.open).toHaveBeenCalledWith(ModalComponent, { size: 'sm' });
  });

然而,我的 e2e 测试看起来更像:

  it('should have an Open button on the home page, the button should open a modal with an OK option (returning TRUE)', async () => {
    page.navigateTo();

    const button = await page.getButton();
    expect(button.getText()).toBe('Open');
    await button.click();

    const modal = await page.getConfirmationModal();
    expect(await modal.isEnabled()).toBeTruthy();

    const acceptBtn = await page.getAcceptButton();

    expect(await acceptBtn.isDisplayed()).toBeTruthy();
    expect(await acceptBtn.isEnabled()).toBeTruthy();
    expect(await acceptBtn.getText()).toBe('OK');
    await acceptBtn.click();
  });

这不是最优雅的测试(如果我花更多的时间,它会测试更多的领域,但我相信你能做到这一点)。

我还要说,这种方式并不完全正确,一般的技术并不是真正的,但是,我不完全确定在单元测试中分析 DOM 事件将如何工作。

尽管测试逻辑是完全可能的(目的(IMO))。

https://github.com/Isolated-/angular-dialog-example-stack-overflow

我希望这在某种程度上有助于解决您的挫败感,如果我有错误的想法,请告诉我,我会纠正它!


推荐阅读