Angular $ timeout方法的Jasmine单元测试

Angular $ timeout方法的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在这段代码被使用,因为它是重要的是如何某些图像当我在渲染幻影(一个图像渲染库)的上下文。当我运行测试,我得到以下错误:

Expected spy flush to have been called. 

的具体问题,我已经是以下两行在我的测试:

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

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

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

+0

'flush'是一种只存在于'ngMock'中的方法,可以从测试中调用。所以窥视刷新只会检查你是否从测试中调用它。这是你的测试,你知道你做了/没有,所以你为什么要检查它? –

当你写单元测试,你必须调用$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的工作示例。

+0

嗨,谢谢高拉夫!我需要监视任何事情吗?或者我假设调用'$ timeout.flush()',然后检查期望? – theGreenCabbage

+0

当你调用'$ timeout.flush()'时,它会清除你测试中意味着的所有'$ timeout()',你可以写出类似'expect(function(){$ timeout)的断言。verifyNoPendingTasks()})。not.toThrow()'。 – Gaurav

+0

不,你不需要监视任何东西,因为'$ timeout'是你单元测试中'ngMock'提供的一个模拟服务对象。 – Gaurav

如果你想刺探$超时,你需要实际replace it与间谍的一种module.decorator电话。但是,您可能想问问自己,是否真正有意义地对您的指令的内部进行微观管理。