Javascript 基于角度$timeout方法的Jasmine单元测试

Javascript 基于角度$timeout方法的Jasmine单元测试,javascript,angularjs,unit-testing,jasmine,karma-jasmine,Javascript,Angularjs,Unit Testing,Jasmine,Karma Jasmine,我的角度应用程序中有以下控制器 m = angular.module "myapp.dashboards" m.directive "lkDashboardElement", ( $timeout MyAppSettings )-> scope: dashboard: "=" element: "=" dashboardController: "=" elementLoa

我的角度应用程序中有以下控制器

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(->
              ..
              ..
            )
我删除了很多东西,所以只有重要的部分显示出来。我遇到麻烦的是我对角度的使用。我当前正在检查某个条件
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间谍,您不能只使用
spyOn
$timeout
,因为它需要对类和方法的引用


因此,我不太确定如何继续前进。我将感谢任何帮助-谢谢

编写单元测试时,必须调用
$timeout.flush()
,然后调用
$timeout.verifyNoPendingTasks()

verifyNoPendingTasks()
将在存在任何挂起的超时时引发异常,因此基本上,您可以断言该异常从未像
expect(函数(){$timeout.verifyNoPendingTasks()})那样引发过。not.toThrow()
。此外,您还可以将预期写为
expect(函数(){$timeout.flush()})

如果在控制器中,
$timeout
有一个固定的时间,如
$timeout(function(){},1000)
,那么在单元测试中,您可以
作为
$timeout.flush(1000)
刷新

你可以在网站上阅读更多


此外,您还可以查看下面的工作示例。

如果您想监视$timeout,则需要使用spy实际执行module.decorator调用。但是,您可能想问问自己,在这种程度上对指令的内部进行微观管理是否真的有意义。

嘿,谢谢Gaurav!我需要监视什么吗?或者我假设调用
$timeout.flush()
,然后检查expects?当调用
$timeout.flush()
时,它会清除所有
$timeout()
,这意味着在测试中,您可以编写类似于
expect(function(){$timeout.verifyNoPendingTasks()})的断言,您不需要监视任何东西,因为
$timeout
是由
ngMock
在单元测试中提供的模拟服务对象。谢谢-我刚刚尝试了这个。我添加了
$timeout.flush();expect($timeout.verifyNoPendingTasks()).not.toThrow()
dashboard.elements=…
之后,但我收到了以下错误:
不需要更多请求,测试退出。这是预期的吗?上述错误可能是由于空的$http请求队列造成的。如果您发出任何http请求,您可能需要查看
flush
是一种仅存在于
ngMock
中的方法,该方法将从测试中调用。因此,监视flush只会检查您是否在测试中调用了它。这是你的测试,你知道你做了/没有,那你为什么要检查它?