使用jasmine进行单元测试的mock angularjs服务

时间:2014-01-22 07:42:14

标签: angularjs jasmine

我有一个Angular App,我想使用 jasmine 为它创建单元测试用例。
在我的 AngularJS 应用中,我的服务为:

var canceler;
var myServices = angular.module('myServices', ['ngResource'])

myServices.factory('getData', ['$http', '$q', function($http, $q){
    var canceler;
    return {
        setData: function(url, callback, error) {
                    canceler = $q.defer();
                    $http.post(url, {}, {timeout:canceler.promise}).success(callback).error(error);
        },
        abort: function(){ canceler.resolve();}
    }
}]);

控制器正在使用此服务。

现在我如何为我在controllerSpecs.js中使用的注入器提供“getData”服务的模拟(用于使用jasmine进行单元测试)。

作为参考,controllerSpecs.js的代码在Getting error while using Jasmine with AngularJS中定义。

2 个答案:

答案 0 :(得分:11)

您可以使用AngularJS的$provide服务。 This page演示了如何使用Jasmine's spies模拟服务的功能。基本上在您的Jasmine测试中,您可以包括:

var getDataMock;

beforeEach(function() {
  getDataMock = {
    setData: jasmine.createSpy(), 
    abort: jasmine.createSpy()
  };

  module(function($provide) {
    $provide.value('getData', getDataMock);
  });
});

这告诉AngularJS,不使用真正的getData服务,而是使用模拟代替它。在此示例中,使用Jasmine间谍进行模拟可以让您轻松创建有关控制器如何以及何时调用getData服务的期望。您也可以将getDataMock设置为任何其他对象,但支持与真实getData服务相同的API是有意义的。

对于奖励积分,您可以在单独的文件中指定getDataMock对象,以便模拟可以在任何数量的单元测试中轻松使用,其中被测试的东西使用getData。但是,这需要使用您正在使用的任何Jasmine运行器进行一些配置。

这就是假设您希望对控制器进行单元测试。如果您想对getData服务本身进行单元测试,AngularJS专门为http请求提供了一个很好的mocking utility

答案 1 :(得分:2)

尝试这样的事情

//creation mock service
var mockGetData = {
  data: [],
  setData: function(url, callback, error){
    //emulate real work, any logic can be here
    data.push('called');
    callback(data);
  }
}

使用模拟服务

it('test description', inject(function ($rootScope, $controller){
  var scope = $rootScope.$new();
  var ctrl = $controller('TodoController', { $scope: scope, getData: mockGetData });
  //some test here....
}))