【问题标题】:Testing $interval in Jasmine/ Karma在 Jasmine/ Karma 中测试 $interval
【发布时间】:2016-05-25 07:39:12
【问题描述】:

我有一个简单的工厂

angular.module('myApp.dice',[]).factory('Dice', ['$interval', function($interval){
    return {
      rollDice: function(){
        return $interval(function(c){
               count++;
          }, 100, 18, false, 0);
      }
    };
}]);

在我的测试用例中

describe('rolling dice', function(){
      var promise, promiseCalled = false, notify = false;
      beforeEach(inject(function(){
        promise = Dice.rollDice();
        promise.then(function(){
          promiseCalled = true;
        });

      }));

      it('should invoke a promise', inject(function(){
        expect(promise).toBeDefined();
      }));

      it('should set promiseCalled', inject(function($rootScope, $interval){


        expect(promiseCalled).toEqual(true);
      }));
    });

如何触发间隔或解决承诺?让测试为真?

【问题讨论】:

    标签: angularjs jasmine karma-runner karma-jasmine angular-mock


    【解决方案1】:

    plunker

    您需要使用来自 angularjs-mocks 的'$interval.flush',然后测试结果。我冒昧地将 count 分配给 dice 对象,因为它在您的代码示例中未定义。

    $intervalinvokeApply = false 一起调用有什么原因吗?因为那你必须手动调用$apply

    测试用例是:

    describe('rolling dice', function(){
        var $interval, $rootScope, dice;
    
        beforeEach(module('plunker'));
    
        beforeEach(inject(function(_$interval_, _$rootScope_, _Dice_){
          $interval = _$interval_;
          $rootScope = _$rootScope_;
          dice = _Dice_;
        }));
    
        it('should increment count', inject(function(){
          dice.rollDice();
          // Move forward by 100 milliseconds
          $interval.flush(100);
          // Need to call apply because $interval was called with invokeApply = false
          $rootScope.$apply();
          expect(dice.count).toBe(1);
        }));
      });
    

    与工厂:

    app.factory('Dice', ['$interval', function($interval){
        var self= {
          count: 0,
          rollDice: function(){
            return $interval(function() {
                  self.count++;
              }, 100, 18, false, 0);
          }
        };
        return self;
    }]);
    

    编辑: 我更喜欢测试函数调用的结果,但也许你有一个用例来测试调用了一个 promise 函数,所以这可能就是你要找的。从$interval 上的角度文档中,它说它返回了

    将在每次迭代时通知的承诺。

    关键字被通知。从promise API then 的参数是

    then(successCallback, errorCallback, notifyCallback)
    

    即对于$interval 的每次迭代,都会调用第三个回调函数notifyCallback。所以测试看起来像这样:

    it('should set promiseCalled', function(){
      var promiseCalled = false;
      dice.rollDice().then(null, null, function() {
        promiseCalled = true;
      });
      $interval.flush(100);
      $rootScope.$apply();
      expect(promiseCalled).toBe(true);
    });
    

    如果你想测试一个已解决的承诺,那么它看起来像这样:

    it('should resolve promise', function(){
      var promiseCalled = false;
      var resolvedData = null;
      $q.when('Some Data').then(function(data) {
        promiseCalled = true;
        resolvedData = data;
      });
      $rootScope.$apply();
      expect(promiseCalled).toBe(true);
      expect(resolvedData).toBe('Some Data');
    });
    

    我已经用这些测试用例更新了 plunker。

    【讨论】:

    • 啊啊啊啊……谢谢。在之前的代码中,我有$interval.flush,但$rootScope.$apply 是新的......
    • 我只是意识到这个问题虽然解决了一个问题并没有回答一个相关的问题......我如何测试来自$interva()promise回调事件返回跨度>
    • @Kendall 更新答案以解决您的最后评论
    猜你喜欢
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 2014-05-04
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多