【问题标题】:How to test Window beforeunload event method - Angular Unit Test如何在卸载事件方法之前测试 Window - Angular 单元测试
【发布时间】:2020-06-19 12:38:17
【问题描述】:

我在一个 Angular 8 项目中工作。

如果用户试图离开网站,我想让窗口发出确认提示,我可以通过将此功能添加到我的组件来做到这一点。

@HostListener("window:beforeunload", ["$event"])
  unloadNotification($event: any) {
    if (this.confirmNavigation) {
      $event.returnValue = true;
    }
  }

现在我正试图弄清楚如何对此进行单元测试,但我不知道该怎么做。我需要模拟窗口才能触发事件吗?我会制作某种事件对象并直接用它调用unloadNotification(虽然不知道如何验证它的结果)?

我什至确定在单元测试中是否需要这样做,它更像是一个集成测试吗?

我还需要确保当我在 karma 中运行测试时实际上并未触发此提示(因为它会停止测试)。所以我需要嘲笑它吗?

另外,我想我想在 afterEach 测试中销毁这个监听器,但不知道怎么做。

任何帮助将不胜感激,谢谢。

【问题讨论】:

    标签: angular unit-testing testing window onbeforeunload


    【解决方案1】:

    此单元测试解决方案使用了模拟概念。如果具有卸载通知的方法是抽象类,则此解决方案有效。并在另一个组件中扩展。

    具有 unloadNotification 方法的文件

         export abstract class ComponentCanDeactivate {
          abstract canDeactivate(): Observable<boolean>;
        
          constructor() { }
        
          @HostListener('window:beforeunload', ['$event'])
          async unloadNotification($event: any) {
            this.canDeactivate().subscribe(data => {
              if (data) {
                $event.returnValue = true;
              }
            });
          }
    
    }

    扩展抽象类的测试组件

    @Component({
        selector: 'test-can-deactivate-mock-host',
        template: '<div></div>',
    })
    export class CanDeactivateTestComponent extends ComponentCanDeactivate {
        returnValue: boolean;
    
        constructor() {
            super();
        }
    
        canDeactivate(): Observable<boolean> {
            return of(this.returnValue);
        }
    }

    单元测试

    describe('ComponentCanDeactivate', () => {
        let componentCanDeactivate: ComponentCanDeactivate;
        let canDeactivateTestComponent: CanDeactivateTestComponent;
        beforeEach(() => {
            TestBed.configureTestingModule({
                imports: [MatDialogModule],
                providers: [
                    ComponentCanDeactivate,
                    CanDeactivateTestComponent
                ],
            });
            componentCanDeactivate = TestBed.get(ComponentCanDeactivate);
            canDeactivateTestComponent = TestBed.get(CanDeactivateTestComponent);
        });
    
        it('should be created', () => {
            expect(componentCanDeactivate).toBeDefined();
        });
    
        it('unloadNotification() should perform close event ', () => {
            const canDeactivateSpy = spyOn(canDeactivateTestComponent, 'canDeactivate').and.returnValue(of(true));
            canDeactivateTestComponent.unloadNotification({});
            expect(canDeactivateTestComponent).toBeDefined();
            expect(canDeactivateSpy).toHaveBeenCalled();
        });
    });

    【讨论】:

    • this.canDeactivate();构造函数主体或 ngOnInit(){} 中缺少代表它,这是@Ashwin 提供的如此优雅的解决方案,谢谢!对此的测试为我节省了很多时间,并且管理这个抽象类,棒极了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    • 1970-01-01
    • 2012-12-15
    • 2018-04-17
    • 2016-10-20
    相关资源
    最近更新 更多