Reputation: 1613
I have an Angular App and I want to create unit test cases for it using jasmine.
In my AngularJS app, I have a service as :
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();}
}
}]);
This service is being used by controller.
Now how can I provide a mock for this "getData" service to the injector I am using in controllerSpecs.js (for the unit testing using jasmine).
For the reference, the code of controllerSpecs.js is defined in Getting error while using Jasmine with AngularJS.
Upvotes: 7
Views: 12665
Reputation: 2661
Try something like this
//creation mock service
var mockGetData = {
data: [],
setData: function(url, callback, error){
//emulate real work, any logic can be here
data.push('called');
callback(data);
}
}
and use of the mock service
it('test description', inject(function ($rootScope, $controller){
var scope = $rootScope.$new();
var ctrl = $controller('TodoController', { $scope: scope, getData: mockGetData });
//some test here....
}))
Upvotes: 2
Reputation: 845
You can use AngularJS's $provide
service. This page demonstrates how to mock the functionality of a service using Jasmine's spies. Basically in your Jasmine test you can include:
var getDataMock;
beforeEach(function() {
getDataMock = {
setData: jasmine.createSpy(),
abort: jasmine.createSpy()
};
module(function($provide) {
$provide.value('getData', getDataMock);
});
});
This tells AngularJS that instead of using the real getData
service, the mock will be used in its place. In this example, using a Jasmine spy for the mock lets you easily create expectations about how and when the getData service is called by the controller. You can alternatively set getDataMock
to any other object, though it makes sense to support the same API as the real getData
service.
For bonus points, you can specify the getDataMock
object in a separate file, so that the mock may be easily used in any number of unit tests where the thing being tested uses getData
. This however requires some configuration with whatever Jasmine runner you are using.
This is all assuming you wish to unit test the controller. If you want to unit test the getData
service itself, AngularJS provides a nice mocking utility specifically for http requests.
Upvotes: 11