Angular $ timeout方法的Jasmine单元测试

时间:2017-02-21 17:46:35

标签: javascript angularjs unit-testing jasmine karma-jasmine

我的Angular应用程序中有以下控制器。

m = angular.module "myapp.dashboards"

    m.directive "lkDashboardElement", (
      $timeout
      MyAppSettings
    )->

      scope:
        dashboard: "="
        element: "="
        dashboardController: "="
        elementLoaded: "&"

      link: ($scope, $el)->

        if MyAppSettings.shouldCalculateTableWidth

          document.addEventListener "dashboard.element.rendered", =>

            $timeout(->
              ..
              ..
            )

我删除了很多东西,所以只有重要部分显示出来。我遇到麻烦的事情与我对Angular $timeout的使用有关。我目前正在检查某个条件shouldCalculateTableWidth,如果我看到事件发生,我会立即超时。

目前我正在尝试编写一个单元测试来检查是否正在使用$timeout

这是我的测试:

describe "in a phantomjs context", ->
  beforeEach ->
    # This sets our Phantom rendering context to true for testing purposes
    MyAppSettings._setIsPhantomRendering(true)

  afterEach ->
    MyAppSettings._setIsPhantomRendering(false)

  it "uses $timeout (instead of applyAsync) for adjusting table widths", ->
    # Creates a dummy dashboard
    dashboardController.queryMap = {1: {view: "foo", model: "bar"}}
    dashboard.elements = [{id: 1}]
    spyOn($timeout, "flush")
    expect($timeout.flush).toHaveBeenCalled()

我想要做的只是测试是否在这段代码中使用$timeout,因为当我在Phantom(图像渲染库)上下文中时,如何渲染某些图像非常重要。当我运行测试时,我收到以下错误:

Expected spy flush to have been called.

我的具体问题是我的测试中有以下两行:

spyOn($timeout, "flush")
expect($timeout.flush).toHaveBeenCalled()

首先,我不相信我正在为$timeout调用正确的方法。在我的控制器中非常清楚,我正在呼叫$timeout,而不是$timeout.flush。其次,对于Jasmine Spys,你不能只spyOn $timeout,因为它需要对类和方法的引用。

所以我不太确定如何继续前进。我将不胜感激任何帮助 - 谢谢!

2 个答案:

答案 0 :(得分:1)

在编写单元测试时,您必须致电$timeout.flush(),然后致电$timeout.verifyNoPendingTasks();

如果有任何挂起超时,

verifyNoPendingTasks()将抛出异常,因此基本上,您可以断言异常永远不会像expect(function () {$timeout.verifyNoPendingTasks()}).not.toThrow()那样抛出。此外,您可以将期望值写为expect(function () {$timeout.flush()}).toThrow()

如果您的控制器$timeout中有$timeout(function() {}, 1000)之类的固定时间,那么在您的单元测试中,您可flush$timeout.flush(1000)

您可以在here了解更多信息。

此外,您可以查看以下CodePen作为工作示例。

答案 1 :(得分:0)

如果你想监视$ timeout,你需要在一个带有间谍的module.decorator调用中实际replace it。但是你可能想问自己,在这种程度上微调你指令的内部是否真的有意义。