简体   繁体   English

如何在AngularJS中使用Jasmine测试$ scope。$ watch

[英]How to test $scope.$watch properly with Jasmine in AngularJS

I'm new to AngularJS and unit testing, 我是AngularJS和单元测试的新手,
I'm testing a list that gets changing by selected category. 我正在测试一个列表,该列表会根据所选类别进行更改。
The test is passing but only if I use the httpBackend.expectGET() that expects the XMLHttpRequest from the "getSomethingElse" method. 该测试通过了,但是仅当我使用期望从“ getSomethingElse”方法获得XMLHttpRequest的httpBackend.expectGET()时,该测试才通过。
I also tried to use the scope.$digest() but I got the same results... 我也尝试使用scope。$ digest(),但是得到了相同的结果...

The Controller: 控制器:

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;
      });
    }
  });
}]);

The Service: 服务:

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');
  };
}]);

The Test 考试

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();
  });
});

The test is passing but only if I use the httpBackend.expectGET() that expects the XMLHttpRequest from the "getSomethingElse" method. 该测试通过了,但是仅当我使用期望从“ getSomethingElse”方法获得XMLHttpRequest的httpBackend.expectGET()时,该测试才通过。

This is because your myServiceMock is not replacing the original myService . 这是因为您的myServiceMock不会替换原始的myService You have various ways to test this - one of them is given below. 您可以通过多种方法进行测试-下面提供了一种方法。 Here we are replacing myService with the service mock:- 在这里,我们将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
      });

    });
  });

You can add your watcher like this. 您可以像这样添加您的观察者。

$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;
    });
  }
}

and in Unit testing just create new it construct for that handler 在单元测试中,只需为该处理程序创建新的it构造

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
});

that way, if&else clauses will be taken in the test. 这样,if&else子句将在测试中被采用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM