单元测试中的AngularJS控制器实例化 - 不绑定到范围值的函数

时间:2014-05-28 21:58:18

标签: angularjs unit-testing jasmine

我有一个同步将数据返回给控制器的服务:

angular.module('app').controller(function($scope, myService) {
  $scope.foo = myService.getFoo();
});

这在浏览器中工作得很好。在我的单元测试中,$scope.foo未定义:

beforeEach(function () {
  module('app');
  myService = jasmine.createSpyObj('myService', ['getFoo']);

  inject(function($controller, $rootScope) {
    $scope = $rootScope.$new();
    ctrl = $controller('ModelSliderCtrl', {
      myService: myService,
      $scope: $scope
    });
  });
});

it('should have foo on the scope', function() {
  myService.getFoo.and.returnValue({});

  expect(myService.getFoo).toHaveBeenCalled();  // PASS
  $scope.$digest();
  expect($scope.foo).toBeDefined();  // FAIL - $scope.foo is undefined
});

在浏览器和测试中都有效:

angular.module('app').controller(function($scope, myService) {
  $scope.init = function() {
    $scope.foo = myService.getFoo();
  };

  $scope.init();
});

it('should have foo on the scope', function() {
  myService.getFoo.and.returnValue({});

  $scope.init();
  expect(myService.getFoo).toHaveBeenCalled();  // PASS
  expect($scope.foo).toBeDefined();  // PASS
});

我想相信我对Angular,Jasmine和JavaScript非常精通。我也问了一些同样困惑的同事。

有人可以向我解释这里发生了什么吗?

1 个答案:

答案 0 :(得分:1)

您正在设置模拟

it('should have foo on the scope', function() {
  myService.getFoo.and.returnValue({});

在实例化控制器之后。那时设置模拟已经太晚了,在实例化控制器之前就这样做了,因为你正在执行init()

  myService = jasmine.createSpyObj('myService', ['getFoo']);
  myService.getFoo.and.returnValue({});

  inject(function($controller, $rootScope) {