Mastering Web Application

(Rick Simeone) #1

Communicating with a Back-end Server


Testing code that interacts with $http


Testing code calling external HTTP services is often problematic due to network
latency and changing data. We want our test to run fast and be predictable.
Fortunately, AngularJS provides excellent mocks to simulate HTTP responses.


In AngularJS the $http service depends on another, lower-level service $httpBackend.
We can think of the $httpBackend as a thin wrapper over the XMLHttpRequest object.
This wrapper masks browsers incompatibilities and enables JSONP requests.


Application code should never call the $httpBackend directly as
the $http service provides a much better abstraction. But having
a separate $httpBackend service means that we can swap it for a
mock one during testing.

To see the $httpBackend mock applied to a unit tests we are going to examine a test
for a sample controller triggering a GET request via the $http service. Here is the
code for the controller itself:


.controller('UsersCtrl', function ($scope, $http) {

$scope.queryUsers = function () {
$http.get('http://localhost:3000/databases/ascrum/collections/
users')

.success(function (data, status, headers, config) {
$scope.users = data;
}).error(function (data, status, headers, config) {
throw new Error('Something went wrong...');
});
};
});

To test this controller's code we can write:


describe('$http basic', function () {

var $http, $httpBackend, $scope, ctrl;
beforeEach(module('test-with-http-backend'));
beforeEach(inject(function (_$http_, _$httpBackend_) {
$http = _$http_;
$httpBackend = _$httpBackend_;
}));
beforeEach(inject(function (_$rootScope_, _$controller_) {
$scope = _$rootScope_.$new();
ctrl = _$controller_('UsersCtrl', {
Free download pdf