Reputation: 1297
Hey I am new to AngularJS testing, I am trying to figure out,
How should I test an AngularJS service which is responsible for my rest calls.
How do I called this service in other controllers which I want to test.
I need to test the datafactory service which use rest requests The code which need to be tested is like this:
var app = angular.module("app",[]);
app.controller("mainCTRL", ["$scope","dataFactory",function($scope,dataFactory){
$scope.title = "Hello World";
dataFactory.getEntries("fakeSuffix");
}]);
app.factory('dataFactory', ['$http', '$window', '$log', function ($http, $window, $log) {
var urlBase = $window.location.origin + '/api',
dataFactory = {};
/**
* get all Entries.
**/
dataFactory.getEntries = function (suffix) {
$log.debug("************ Get All Entries ************");
$log.debug("url:", urlBase + suffix);
return $http.get(urlBase + suffix, { headers: { cache: false } });
};
/**
* get single Entry.
**/
dataFactory.getEntry = function (id) {
$log.debug("************ Get Single Entry ************");
return $http.get(urlBase + '/' + id);
};
/**
* insert Entry
**/
dataFactory.postEntry = function (method, entry) {
var url = urlBase + '/' + method;
return $http.post(url, entry);
};
/**
* update Entry
**/
dataFactory.updateEntry = function (entry) {
$log.debug("************ Update Single Entry ************");
return $http.put(urlBase + '/' + entry.id, entry);
};
/**
* delete Entry
**/
dataFactory.deleteEntry = function (id) {
$log.debug("************ Delete Single Entry ************");
return $http.delete(urlBase + '/' + id);
};
return dataFactory;
}]);
<script src="https://ajax.googleapis.com/ajax/libs/jQuery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div id="block" ng-app="app" ng-controller="mainCTRL">
{{title}}
</div>
Upvotes: 0
Views: 1142
Reputation: 39432
Q.1 - How should I test an AngularJS service which is responsible for my rest calls.
Ans. - I've written a test case for one of your services' methods below. You can write similar test cases for other methods.
Q.2 - How do I called this service in other controllers which I want to test.
Ans. - In the code below, as you are writing test cases for your service which is relying on $http
's get
, post
, put
and delete
methods, I've injected $httpBackend
in the test cases and mocked all these methods in beforeEach
block. Similarly, when you'll be writing test cases for your controller which would be depending on this service, you'll have to use a similar approach. Just inject the service in your controller's test case and mock all the methods of your service that would be called from your controller.
//AngularJS Code
var app = angular.module("app",[]);
app.controller("mainCTRL", ["$scope","dataFactory",function($scope,dataFactory){
$scope.title = "Hello World";
dataFactory.getEntries("fakeSuffix");
}]);
app.factory('dataFactory', ['$http', '$window', '$log', function ($http, $window, $log) {
//var urlBase = $window.location.origin + '/api',
var urlBase = '/api', //Change here.
dataFactory = {};
/**
* get all Entries.
**/
dataFactory.getEntries = function (suffix) {
$log.debug("************ Get All Entries ************");
$log.debug("url:", urlBase + suffix);
return $http.get(urlBase + suffix, { headers: { cache: false } });
};
/**
* get single Entry.
**/
dataFactory.getEntry = function (id) {
$log.debug("************ Get Single Entry ************");
return $http.get(urlBase + '/' + id);
};
/**
* insert Entry
**/
dataFactory.postEntry = function (method, entry) {
var url = urlBase + '/' + method;
return $http.post(url, entry);
};
/**
* update Entry
**/
dataFactory.updateEntry = function (entry) {
$log.debug("************ Update Single Entry ************");
return $http.put(urlBase + '/' + entry.id, entry);
};
/**
* delete Entry
**/
dataFactory.deleteEntry = function (id) {
$log.debug("************ Delete Single Entry ************");
return $http.delete(urlBase + '/' + id);
};
return dataFactory;
}]);
//Jasmine Test Case
describe('factory: dataFactory', function() {
var dataFactory, $http, $window, $log, $httpBackend;
beforeEach(module('app'));
beforeEach(inject(function (_dataFactory_, _$http_, _$window_, _$log_, _$httpBackend_) {
dataFactory = _dataFactory_;
$http = _$http_;
$window = _$window_;
$log = _$log_;
$httpBackend = _$httpBackend_;
$httpBackend.when('GET', "/api/suffix").respond({
status: 200,
data: "data"
});
$httpBackend.when('GET', "/api/id").respond({
status: 200,
data: "data"
});
$httpBackend.when('POST', "/api/method").respond({
status: 200,
data: "data"
});
$httpBackend.when('PUT', "/api/id").respond({
status: 200,
data: "data"
});
$httpBackend.when('DELETE', "/api/id").respond({
status: 200,
data: "data"
});
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
describe('function: getEntries', function(){
//A sample test case for getEntries
it('should get all enteries', function(){
var response = dataFactory.getEntries("/suffix");
response.then(function(res){
expect(res.status).toEqual(200);
});
$httpBackend.flush();
});
});
//Similarly write tests for the rest of functions.
});
Hope this helps.
Upvotes: 1
Reputation: 66560
Try this, found in answer to this question Injecting a mock into an AngularJS service
module(function($provide) {
$provide.value('$http', {
get: function(url, options) {
// your get implementation
},
post: function(url, data) {
// your post implementation
},
'delete': function(url) {
// your delete implementation
},
put: function(url, data) {
// your put implementation
}
});
});
Upvotes: 1
Reputation: 1129
As for as I know, To test service, create the Jasmine test case similar to controller with out controller initialisation.
To Test the controllers based on service response create spyOn for the respective service and mock the service response.
Upvotes: 1