angular - 测试包含 setTimeout() 的函数

标签 angular testing jasmine settimeout karma-jasmine

我的组件中有一个关闭函数,它包含一个 setTimeout() 以便为动画完成提供时间。

public close() {
    this.animate = "inactive"
    setTimeout(() => {
       this.show = false
    }, 250)
}

this.show 绑定(bind)到 ngIf

this.animate 绑定(bind)到动画。

我有个测试需要测试这个功能

it("tests the exit button click", () => {
  comp.close()
  fixture.detectChanges()
  //verifies the element is no longer in the DOM
  const popUpWindow = fixture.debugElement.query(By.css("#popup-window"))
  expect(popUpWindow).toEqual(null)
})

当有 setTimeout() 时,如何正确测试此函数?

我正在使用 jasmine.clock().tick(251) 但窗口永远不会消失。对此有什么想法吗?

最佳答案

你可以做以下两件事之一:

1:在 setTimeout() 中实际等待测试 250+1 毫秒,然后检查元素是否真的消失了。

2: 在测试中使用fakeAsync()tick() 来模拟时间——一个tick() 将解决setTimeout in原始的 close(),检查可能会在 fixture.whenStable().then(...) 之后立即发生。

例如:

it("tests the exit button click", fakeAsync(() => {
  comp.close()
  tick(500)
  fixture.detectChanges()

  fixture.whenStable().then(() => {
    const popUpWindow = fixture.debugElement.query(By.css("#popup-window"))
    expect(popUpWindow).toBe(null)
  })
}))

我建议使用第二种方法,因为它比实际等待原始方法快得多。如果您仍然使用第一个,请尝试降低测试前的超时时间以使其运行得更快。

服务

对于服务,您不需要在 tick 之后调用 detectChanges,也不需要将 expect 语句包装在 whenStable 中。您可以在勾选之后立即执行您的逻辑。

  it('should reresh token after interval', fakeAsync(() => {
    // given
    const service: any = TestBed.get(CognitoService);
    const spy = spyOn(service, 'refreshToken').and.callThrough();
    ....
    // when
    service.scheduleTokenRefresh();
    tick(TOKEN_REFRESH_INTERVAL);
    // then
    expect(spy).toHaveBeenCalled();
  }));

关于angular - 测试包含 setTimeout() 的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41772989/

相关文章:

javascript - 文档元素的模拟对象

node.js - ng build --prod 不适用于 Docker 容器

unit-testing - 如何在 rspec 单元测试中隔离 Puppet 函数模拟

javascript - Angular Material 拖放 : Custom Pipe Issue

c# - 线程的编码 UI 测试问题/定期执行重复操作

http - 如何测试 mochiweb 应用程序?

javascript - NodeJS、WebStorm 和 Jasmine : ReferenceError: describe is not defined when debugging

typescript - 如何模拟 FileReader 的失败

angular - 如何在 Angular 5 中使用 MatTableDataSource 创建自定义过滤?

node.js - 未捕获( promise ): Response with status: 0 in Angular2/Ionic2