我有一个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中定义。
答案 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....
}))