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

r.b*_*waj 6 jasmine angularjs

我有一个Angular应用程序,我想使用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();}
    }
}]);
Run Code Online (Sandbox Code Playgroud)

控制器正在使用此服务.

现在,我如何为我在controllerSpecs.js中使用的注入器提供此"getData"服务的模拟(对于使用jasmine的单元测试).

作为参考,在使用Jasmine和AngularJS时,Getting错误中定义了controllerSpecs.js的代码 .

jel*_*son 11

您可以使用AngularJS的$provide服务.此页面演示了如何使用Jasmine的间谍模拟服务的功能.基本上在您的Jasmine测试中,您可以包括:

var getDataMock;

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

  module(function($provide) {
    $provide.value('getData', getDataMock);
  });
});
Run Code Online (Sandbox Code Playgroud)

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

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

这是假设您希望对控制器进行单元测试.如果您想对getData服务本身进行单元测试,AngularJS 专门为http请求提供了一个很好的模拟实用程序.

  • 答案中的链接已经死了 (2认同)

Igo*_*rCh 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

以及模拟服务的使用

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