【问题标题】:AngularJS: spyOn both $timeout and $timeout.cancelAngularJS:监视 $timeout 和 $timeout.cancel
【发布时间】:2014-04-09 08:39:37
【问题描述】:

在使用 Jasmine 的 spyOn 方法测试同时使用 $timeout$timeout.cancel 的 AngularJS 应用程序的一部分时。

describe('<whatever>', function() {

  beforeEach(function() {
    spyOn(this, '$timeout').andCallThrough();
    spyOn(this.$timeout, 'cancel').andCallThrough();
    this.createController();
  });

  it('should <whatever>', function() {
    expect(this.$timeout).toHaveBeenCalled();
    expect(this.$timeout.cancel).toHaveBeenCalled();
  });

});

您应该在您的应用程序代码中遇到以下错误,该错误正在使用您的测试注入其中的内容。

TypeError: 'undefined' is not a function (evaluating '$timeout.cancel(timeoutPromise)');

【问题讨论】:

    标签: angularjs timeout jasmine


    【解决方案1】:

    如果您要在测试套件中运行 console.log(Object.keys(this.$timeout));,您将看到以下输出;

    LOG: ['identity', 'isSpy', 'plan', 'mostRecentCall', 'argsForCall', 'calls', 'andCallThrough', 'andReturn', 'andThrow', 'andCallFake', 'reset', 'wasCalled', 'callCount', 'baseObj', 'methodName', 'originalValue']
    

    $timeout 是一个函数,AngularJS 也在用 cancel 方法装饰——因为函数是对象。因为这不是很常见的事情,Jasmine 用它的间谍实现替换而不是增加 $timeout - 破坏 $timeout.cancel

    解决方法是在 $timeout 被 Jasmine 的 $timeout 间谍覆盖后再次放回 cancel 间谍,如下所示;

    describe('<whatever>', function() {
    
      beforeEach(function() {
        spyOn(this.$timeout, 'cancel').andCallThrough();
        var $timeout_cancel = this.$timeout.cancel;
        spyOn(this, '$timeout').andCallThrough();
        this.$timeout.cancel = $timeout_cancel;
        this.createController();
      });
    
      it('should <whatever>', function() {
        expect(this.$timeout).toHaveBeenCalled();
        expect(this.$timeout.cancel).toHaveBeenCalled();
      });
    
    });
    

    【讨论】:

    • 我不明白为什么 $timeout 在“this”上。我没有看到任何分配它的地方
    • 'this' 是 jasmine 套件的上下文,但您也可以在外部变量范围内使用 vars 来实现相同的效果。
    【解决方案2】:

    这对我来说适用于 $interval,所以它应该适用于 $timeout。 (茉莉花2)

    var $intervalSpy = jasmine.createSpy('$interval', $interval).and.callThrough();

    那么我可以两者都做:

    expect($intervalSpy.cancel).toHaveBeenCalledTimes(1);
    expect($intervalSpy).toHaveBeenCalledTimes(1);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-06
      • 2015-01-04
      • 2016-09-17
      • 1970-01-01
      相关资源
      最近更新 更多