Mock angularjs for unit testing using jasmine

I have an Angular app and I want to create a unit test for it using Jasmine .
In my AngularJS application, I have a service:

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 used by the controller.

Now, how can I provide a layout for this "getData" service for the injector that I use in the Specs.js controller (for unit testing using jasmine).

For reference, the controllerSpecs.js code is defined in Error when using Jasmine with AngularJS .

+6
source share
2 answers

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 using a mock service

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

You can use the AngularJS $provide . This page demonstrates how to mock a service’s functionality using Jasmine 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 getData layout will be used in its place. In this example, using the Jasmine spy for the layout makes it easy to create expectations about how and when the getData service is called by the controller. You can alternatively install getDataMock on any other object, although it makes sense to maintain the same API as the real getData service.

For bonus points, you can specify the getDataMock object in a separate file, so the layout can be easily used in any number of unit tests where the test item uses getData . This, however, requires some configuration with any Jasmine runner that you use.

It is all assumed that you want a unit test controller. If you want the unit test getData service, AngularJS provides a nice mocking utility specifically for http requests.

+11
source

All Articles