如何更新角度模拟服务返回的值?

时间:2015-01-15 00:31:18

标签: angularjs unit-testing mocking

我有一种服务方法,我用它来填充控制器范围内的变量。当我去测试它时,我希望能够模拟服务方法以返回不同的值,以便我可以测试控制器如何响应。为此,我做了以下事情:

var data = 'some data';

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

这确实会返回一些数据'当我在我的范围内断言变量时。但是,当我在测试中更改数据值时,getData()返回的值不会立即更新。

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

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

我知道我错过了一些愚蠢的东西,但我不能把手指放在上面。

Issue duplicated on plunkr

1 个答案:

答案 0 :(得分:0)

您需要在每个测试中初始化控制器,以便在每个断言之前调用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