【问题标题】:Karma angularjs testing: test code in timeout never executesKarma angularjs 测试:超时测试代码永远不会执行
【发布时间】:2014-01-24 09:39:56
【问题描述】:

$timeout 中的以下代码永远不会被调用。我可以在那里放任何我喜欢的错误测试,并且测试总是通过(有一个类似的问题(Karma e2e testing: how to know when the DOM is ready?),但它没有提供解决方案):

it('should display a filter row when attribute sg-live-filtering is present', function()   
{
   angular.mock.inject(function($compile, $rootScope, $timeout) {
      var elem = $compile('<div sg-grid sg-data="api/grid/accounts" sg-live-filtering></div>')(scope); // the angular-kendo grid
      $rootScope.$apply();            
      var table = elem.find('table[role="grid"]'); // find the kendo grid
      expect(table.length).toBe(1);
      var header = table.find('thead'); // find the grid's table header 
      expect(header.length).toBe(1);
      $timeout(function () {
         // get the second row in the header and check it has a specific class
         expect(header.find('tr').eq(1).hasClass('sg-grid-filter-row')).toBeTruthy();
         // e.g. I could do this and it would still pass!!!             
         expect(header.find('tr').eq(500));
      });
   }
} 

PhantomJS 1.9.2 (Windows 7):执行 1 of 871(跳过 383)成功(0 秒 / 0

这是它在浏览器中的样子:

剑道网格是使用标准 angularjs 指令创建的:

angular.module('sgComponents').directive('sgGrid', [
   templateUrl: 'sg-grid.html',
   // lots of kendo code follows to build the grid       
]);

外部 sg-grid.html 模板:

<div sg-grid sg-data="api/grid/accounts"             
     sg-live-filtering> <!-- the attribute I want to test -->        
</div>

当指令代码运行时,会检查是否存在 sg-live-filtering attr。如果是,则调用一个实用函数来将您在图像中突出显示的行附加到网格的表头:

if (attrs.sgLiveFiltering) {
   /*
    timeout is needed to ensure DOM is ready. COULD THIS BE THE PROBLEM?
   */
   $timeout(function () { 
      /*
      this function adds the filter row to the grid. 
      THE NEW ROW HAS CLASS 'sg-grid-filter-row' THAT I USE FOR TESTING
      */
      buildGridFilterRow(elm, scope, attrs);
    });
}

【问题讨论】:

  • 您是否尝试过类似$timeout.flush(100) 的方法来模拟经过的时间?
  • 我会把它放在哪里?在超时块之后还是之前?
  • $compile 之后的任何地方都应该这样做,而且你不需要 $timeout 块,你应该可以直接断言。
  • 好的,谢谢,马上试试

标签: angularjs kendo-grid karma-runner angular-kendo


【解决方案1】:

你能显示你的测试代码吗??? 因为您必须等待才能执行超时或仅使用 $timeout.flush(); 这是一个例子: Unit testing an asynchronous service in angularjs

【讨论】:

  • 你可以在这个问题的第一个灰色块中看到我的测试代码(它('should...)。$timeout.flush() 是上面 idursun 推荐的,但我无法得到它工作。谢谢你的链接,我会读一下。
  • 使用 jasmine 中的 runs 和 waitsFor 方法等待代码执行
【解决方案2】:

终于(2 周后!)让它发挥作用。 @idursun 和 igorzg 在建议使用 $timeout.flush(100) 时是正确的,但正如 @idursun 在他的 cmets 中进一步提到的那样,它还需要删除 $timeout 块。

当我最初尝试这个时,它不起作用,但现在它起作用了。不要问我为什么,我只关心它是否有效!这是我的完整测试用例供参考:

it('should display a filter row when attribute sg-live-filtering is present', function () {
   angular.mock.inject(function($compile, $rootScope, $timeout) {
   var scope = $rootScope.$new();
   scope.accountColumnsForAdvSearch = [
      {field: 'accountId', title: 'AccountId', dataType: 'string'},
      {field: 'name', title: 'Account Name', dataType: 'string'},
      {field: 'shortName', title: 'Short Name', dataType: 'string'},
      {field: 'status', title: 'Status', dataType: 'string'}
   ];

   $httpBackend.when('GET', 'api/grid/accounts').respond(accountData);    

   var elem = $compile('<div sg-grid sg-data="api/grid/accounts" sg-columns="accountColumnsForAdvSearch" sg-live-filtering="true"></div>')(scope);
   $rootScope.$apply();
   $httpBackend.flush();
   $timeout.flush(100); // wait for DOM to load
   var table = elem.find('table[role="grid"]'); // the kendo grid
   expect(table.length).toBe(1);
   var filterRow = table.find('.sg-grid-filter-row'); // the filter row
   expect(filterRow.length).toBe(1);
});

【讨论】:

  • 你在 sg-grid 中使用什么?除了kendo-labs.github.io/angular-kendo,还有别的吗?
  • @WayneBrantley - 刚刚看到你的评论。 sg-grid 是剑道网格,只是我们有自己的指令,称为 sgGrid,然后负责创建剑道网格。
猜你喜欢
  • 1970-01-01
  • 2018-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-08
  • 2015-01-01
  • 2019-11-28
相关资源
最近更新 更多