为什么我在 promise 中测试代码时会丢失我的调用上下文 (angular + jasmine)

Why am I losing my invocation context when testing code inside of a promise (angular + jasmine)

我有一个简单的控制器,我想在其中测试承诺内的机制(在这种情况下,我想测试 foo 在我 运行 bar 时被调用。这是我的控制器:

angular.module('myModule', [])
  .controller('MyCtrl', function ($q) {

  var myPromise = $q.when();

  this.foo = function () {
    console.log('running foo');
  };

  this.bar = function () {
    myPromise.then(function () {
      this.foo();
    });
  };
});

这是我的茉莉花测试:

describe('MyCtrl', function () {
  var $controller, $scope, $q;

  beforeEach(inject(function ($rootScope, _$q_, _$controller_) {
    $controller = _$controller_;
    $q = _$q_;
    $scope = $rootScope.$new();
  }));

  describe('bar function', function () {
    it('should call the foo function', function () {
      var controller = $controller('MyCtrl', { $q: $q });
      spyOn(controller, 'foo');
      controller.bar();
      $scope.$digest();
      expect(controller.foo).toHaveBeenCalled();
    });
  });
});

当我运行这个测试时,我得到这个错误:

TypeError: 'undefined' is not an object (evaluating 'this.foo')

似乎在 then() 函数块内,我丢失了引用控制器的调用上下文。当测试 运行s 并命中 this.foo() 时,this 未定义。

'this' 不包含属性 'foo' 因为上下文(到外部范围)未绑定。

您可以执行以下操作之一:

1.

this.bar = function() {
    var that = this;
    myPromise.then(function () {
        that.foo();
    });
};

2.

this.bar = function() {
    function onSuccess() { this.foo(); }
    myPromise.then(onSuccess.bind(this));
};