如何更新 angular 中模拟服务返回的值?

How do you update the value returned by a mocked service in angular?

我有一个服务方法,用于在我的控制器范围内填充一个变量。当我去测试它时,我希望能够将服务方法模拟为 return 不同的值,以便我可以测试控制器如何响应。为此,我做了以下工作:

var data = 'some data';

ctrl = $controller('MainCtrl', {
  $scope: $scope,
  MyService: {
    getData: function() {
      return data;
    }
  }
});

当我在我的范围内断言变量时,这会 return 'some data'。但是,当我在测试中更改数据值时,从 getData() 编辑的值 return 不会立即更新。

it('should say "more data"', function() {
    data = 'more data';
    expect($scope.data).toEqual(data);
});

通过将数据设置为 'bar',我希望模拟的 getData() 也将我的范围设置为 'bar',但它仍然 returns 'foo'。奇怪的是,如果我在这个测试之后进行另一个测试,我将数据设置为 'baz',那么 $scope.data 就是 'bar'。所以数据的价值正在被设定,但似乎只是落后于测试。在我的测试中设置数据无济于事后,我尝试调用 scope.$apply()。

我知道我遗漏了一些愚蠢的东西,但我无法确定。

Issue duplicated on plunkr

您需要在每个测试中初始化您的控制器,以便在每个断言之前调用 MyService.getData

describe('Test app', function() {
  var $scope = null;
  var ctrl = null;
  var controller = null;
  var _MyService_ = null
  var data = 'some data';

  //mock the service
  angular.module('MyServiceMock', [])
      .value('MyService',{
        getData: function() {
           return data;
        }
      });

  //inject the mock
  beforeEach(module('plunker', 'MyServiceMock'));

  beforeEach(inject(function($rootScope, $controller, MyService) {
    $scope = $rootScope.$new();
    controller = $controller; 
    _MyService_ = MyService;
  }));

  it('should say "some data"', function() {
    ctrl = controller('MainCtrl', {
      $scope: $scope,
      MyService: _MyService_
    });

    expect($scope.data).toEqual(data);
  });

  it('should say "more data"', function() {
    data = 'more data';

    ctrl = controller('MainCtrl', {
      $scope: $scope,
      MyService: _MyService_
    });

    expect($scope.data).toEqual(data);
  });

  it('should say "even more data"', function() {
    data = 'even more data';

    ctrl = controller('MainCtrl', {
      $scope: $scope,
      MyService: _MyService_
    });

    expect($scope.data).toEqual(data);
  });
});

http://plnkr.co/edit/HcZBQFpAtCoUnEncAkJe?p=preview