如何测试$ scope。$在AngularJS中使用Jasmine正确观察

时间:2016-12-23 13:43:41

标签: angularjs unit-testing jasmine

我是AngularJS和单元测试的新手,
我正在测试一个按所选类别进行更改的列表 测试正在通过,但前提是我使用的httpBackend.expectGET()需要来自" getSomethingElse"的XMLHttpRequest。方法。
我也尝试使用范围。$ digest()但我得到了相同的结果......

控制器:

app.controller('mainCtrl', ['$scope', 'myService', function($scope, 
myService) {
  $scope.category = null;

  myService.getSomethingElse().then(function(res) {
    $scope.somethingElse = res.data;
  });

  $scope.$watch('category', function() {
    if ($scope.category !== null) {
      myService.getListByCat($scope.category.name).then(function(res) {
        $scope.list = res.data;
      });
    }
    else {
      myService.getLongList().then(function(res) {
        $scope.list = res.data;
      });
    }
  });
}]);

服务:

app.service('myService', ['$http', function($http) {
  this.getListByCat = function(category) {
    return $http.get('getting-list?cat=' + category);
  };

  this.getLongList = function() {
    return $http.get('getting-long-list');
  };

  this.getSomethingElse = function() {
    return $http.get('getting-something-else');
  };
}]);

测试

describe('Testing mainCtrl', function() {
  var scope, ctrl;

  var myServiceMock = { 
    getSomethingElse: jasmine.createSpy().and.returnValue(1),
    getListByCat: jasmine.createSpy().and.returnValue(2)
  };

  beforeEach(function() {
    module('app');
    inject(function($rootScope, $controller) {
      scope = $rootScope.$new();
      ctrl = $controller('mainCtrl', {
        $scope: scope,
        myService: myServiceMock
      });

    });
  });

  it('should update the list by selected category', function() {
    expect(scope.category).toBeNull();
    expect(scope.list).toBeUndefined();

    scope.category = {
      id: 1,
      name: 'Jobs'
    };

    scope.$apply();

    expect(myServiceMock.getSomethingElse).toHaveBeenCalled();
    expect(myServiceMock.getListByCat).toHaveBeenCalled();
  });
});

2 个答案:

答案 0 :(得分:0)

  

测试正在通过但是只有当我使用httpBackend.expectGET()时才需要来自" getSomethingElse"的" getSomethingElse"方法

这是因为您的myServiceMock未替换原始myService。您可以通过各种方式对此进行测试 - 其中一种方法如下。这里我们用服务模拟替换myService: -

beforeEach(function() {
    module('app');
    module(function($provide){
    $provide.factory('myServiceMock', 
        function(){
           return myServiceMock;
        );
    });
    inject(function($rootScope, $controller) {
      scope = $rootScope.$new();
      ctrl = $controller('mainCtrl', {
        $scope: scope,
        myService: myServiceMock
      });

    });
  });

答案 1 :(得分:-1)

您可以像这样添加您的观察者。

$scope.categoryWatcher = categoryWatcher;
$scope.$watch('category', categoryWatcher);

function categoryWatcher() {
if ($scope.category !== null) {
    myService.getListByCat($scope.category.name).then(function(res) {
      $scope.list = res.data;
    });
  }
  else {
    myService.getLongList().then(function(res) {
      $scope.list = res.data;
    });
  }
}

并在单元测试中为该处理程序创建新的构造

it('should test categoryWatcher for null value', function(){
  $scope.category = null;
  $scope.categoryWatcher();
  // your expectations
});

it('should test categoryWatcher for "desiredValue" value', function(){
  $scope.category = "desiredValue";
  $scope.categoryWatcher();
  // your expectations
});

这样,如果在测试中将采用& else子句。