Improve this Doc View Source $httpBackend
- service in module ngMock
Overview
Fake HTTP backend implementation suitable for unit testing applications that use the $http service.
During unit testing, we want our unit tests to run quickly and have no external dependencies so we don’t want to send XHR or JSONP requests to a real server. All we really need is to verify whether a certain request has been sent or not, or alternatively just let the application make requests, respond with pre-trained responses and assert that the end result is what we expect it to be.
This mock implementation can be used to respond with static or dynamic responses via the expect
and when
apis and their shortcuts (expectGET
, whenPOST
, etc).
When an AngularJS application needs some data from a server, it calls the $http service, which sends the request to a real server using $httpBackend service. With dependency injection, it is easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify the requests and respond with some testing data without sending a request to a real server.
There are two ways to specify what test data should be returned as http responses by the mock backend when the code under test makes http requests:
-
$httpBackend.expect
- specifies a request expectation -
$httpBackend.when
- specifies a backend definition
Request Expectations vs Backend Definitions
Request expectations provide a way to make assertions about requests made by the application and to define responses for those requests. The test will fail if the expected requests are not made or they are made in the wrong order.
Backend definitions allow you to define a fake backend for your application which doesn't assert if a particular request was made or not, it just returns a trained response if a request is made. The test will pass whether or not the request gets made during testing.
Request expectations | Backend definitions | |
---|---|---|
Syntax | .expect(...).respond(...) | .when(...).respond(...) |
Typical usage | strict unit tests | loose (black-box) unit testing |
Fulfills multiple requests | NO | YES |
Order of requests matters | YES | NO |
Request required | YES | NO |
Response required | optional (see below) | YES |
In cases where both backend definitions and request expectations are specified during unit testing, the request expectations are evaluated first.
If a request expectation has no response specified, the algorithm will search your backend definitions for an appropriate response.
If a request didn't match any expectation or if the expectation doesn't have the response defined, the backend definitions are evaluated in sequential order to see if any of them match the request. The response from the first matched definition is returned.
Flushing HTTP requests
The $httpBackend used in production always responds to requests asynchronously. If we preserved this behavior in unit testing, we'd have to create async unit tests, which are hard to write, to follow and to maintain. But neither can the testing mock respond synchronously; that would change the execution of the code under test. For this reason, the mock $httpBackend has a flush()
method, which allows the test to explicitly flush pending requests. This preserves the async api of the backend, while allowing the test to execute synchronously.
Unit testing with mock $httpBackend
The following code shows how to setup and use the mock backend when unit testing a controller. First we create the controller under test:
// The module code angular .module('MyApp', []) .controller('MyController', MyController); // The controller code function MyController($scope, $http) { var authToken; $http.get('/auth.py').then(function(response) { authToken = response.headers('A-Token'); $scope.user = response.data; }).catch(function() { $scope.status = 'Failed...'; }); $scope.saveMessage = function(message) { var headers = { 'Authorization': authToken }; $scope.status = 'Saving...'; $http.post('/add-msg.py', message, { headers: headers } ).then(function(response) { $scope.status = ''; }).catch(function() { $scope.status = 'Failed...'; }); }; }
Now we setup the mock backend and create the test specs:
// testing controller describe('MyController', function() { var $httpBackend, $rootScope, createController, authRequestHandler; // Set up the module beforeEach(module('MyApp')); beforeEach(inject(function($injector) { // Set up the mock http service responses $httpBackend = $injector.get('$httpBackend'); // backend definition common for all tests authRequestHandler = $httpBackend.when('GET', '/auth.py') .respond({userId: 'userX'}, {'A-Token': 'xxx'}); // Get hold of a scope (i.e. the root scope) $rootScope = $injector.get('$rootScope'); // The $controller service is used to create instances of controllers var $controller = $injector.get('$controller'); createController = function() { return $controller('MyController', {'$scope' : $rootScope }); }; })); afterEach(function() { $httpBackend.verifyNoOutstandingExpectation(); $httpBackend.verifyNoOutstandingRequest(); }); it('should fetch authentication token', function() { $httpBackend.expectGET('/auth.py'); var controller = createController(); $httpBackend.flush(); }); it('should fail authentication', function() { // Notice how you can change the response even after it was set authRequestHandler.respond(401, ''); $httpBackend.expectGET('/auth.py'); var controller = createController(); $httpBackend.flush(); expect($rootScope.status).toBe('Failed...'); }); it('should send msg to server', function() { var controller = createController(); $httpBackend.flush(); // now you don’t care about the authentication, but // the controller will still send the request and // $httpBackend will respond without you having to // specify the expectation and response for this request $httpBackend.expectPOST('/add-msg.py', 'message content').respond(201, ''); $rootScope.saveMessage('message content'); expect($rootScope.status).toBe('Saving...'); $httpBackend.flush(); expect($rootScope.status).toBe(''); }); it('should send auth header', function() { var controller = createController(); $httpBackend.flush(); $httpBackend.expectPOST('/add-msg.py', undefined, function(headers) { // check if the header was sent, if it wasn't the expectation won't // match the request and the test will fail return headers['Authorization'] === 'xxx'; }).respond(201, ''); $rootScope.saveMessage('whatever'); $httpBackend.flush(); }); });
Dynamic responses
You define a response to a request by chaining a call to respond()
onto a definition or expectation. If you provide a callback as the first parameter to respond(callback)
then you can dynamically generate a response based on the properties of the request.
The callback
function should be of the form function(method, url, data, headers, params)
.
Query parameters
By default, query parameters on request URLs are parsed into the params
object. So a request URL of /list?q=searchstr&orderby=-name
would set params
to be {q: 'searchstr', orderby: '-name'}
.
Regex parameter matching
If an expectation or definition uses a regex to match the URL, you can provide an array of keys via a params
argument. The index of each key in the array will match the index of a group in the regex.
The params
object in the callback will now have properties with these keys, which hold the value of the corresponding group in the regex.
This also applies to the when
and expect
shortcut methods.
$httpBackend.expect('GET', /\/user\/(.+)/, undefined, undefined, ['id']) .respond(function(method, url, data, headers, params) { // for requested url of '/user/1234' params is {id: '1234'} }); $httpBackend.whenPATCH(/\/user\/(.+)\/article\/(.+)/, undefined, undefined, ['user', 'article']) .respond(function(method, url, data, headers, params) { // for url of '/user/1234/article/567' params is {user: '1234', article: '567'} });
Matching route requests
For extra convenience, whenRoute
and expectRoute
shortcuts are available. These methods offer colon delimited matching of the url path, ignoring the query string and trailing slashes. This allows declarations similar to how application routes are configured with $routeProvider
. Because these methods convert the definition url to regex, declaration order is important. Combined with query parameter parsing, the following is possible:
$httpBackend.whenRoute('GET', '/users/:id') .respond(function(method, url, data, headers, params) { return [200, MockUserList[Number(params.id)]]; }); $httpBackend.whenRoute('GET', '/users') .respond(function(method, url, data, headers, params) { var userList = angular.copy(MockUserList), defaultSort = 'lastName', count, pages, isPrevious, isNext; // paged api response '/v1/users?page=2' params.page = Number(params.page) || 1; // query for last names '/v1/users?q=Archer' if (params.q) { userList = $filter('filter')({lastName: params.q}); } pages = Math.ceil(userList.length / pagingLength); isPrevious = params.page > 1; isNext = params.page < pages; return [200, { count: userList.length, previous: isPrevious, next: isNext, // sort field -> '/v1/users?sortBy=firstName' results: $filter('orderBy')(userList, params.sortBy || defaultSort) .splice((params.page - 1) * pagingLength, pagingLength) }]; });
Methods
-
when(method, url, [data], [headers], [keys]);
Creates a new backend definition.
Parameters
Param Type Details method string
HTTP method.
url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current definition.
data (optional)string
RegExp
function(string)
HTTP request body or function that receives data string and returns true if the data is as expected.
headers (optional)Object
function(Object)
HTTP headers or function that receives http header object and returns true if the headers match the current definition.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled.- respond –
{function([status,] data[, headers, statusText]) | function(function(method, url, data, headers, params)}
– The respond method takes a set of static data to be returned or a function that can return an array containing response status (number), response data (Array|Object|string), response headers (Object), HTTP status text (string), and XMLHttpRequest status (string:complete
,error
,timeout
orabort
). The respond method returns therequestHandler
object for possible overrides.
- respond –
-
matchLatestDefinitionEnabled([value]);
This method can be used to change which mocked responses
$httpBackend
returns, when defining them with $httpBackend.when() (and shortcut methods). By default,$httpBackend
returns the first definition that matches. When setting$http.matchLatestDefinitionEnabled(true)
, it will use the last response that matches, i.e. the one that was added last.hb.when('GET', '/url1').respond(200, 'content', {}); hb.when('GET', '/url1').respond(201, 'another', {}); hb('GET', '/url1'); // receives "content" $http.matchLatestDefinitionEnabled(true) hb('GET', '/url1'); // receives "another" hb.when('GET', '/url1').respond(201, 'onemore', {}); hb('GET', '/url1'); // receives "onemore"
This is useful if a you have a default response that is overriden inside specific tests.
Note that different from config methods on providers,
matchLatestDefinitionEnabled()
can be changed even when the application is already running.Parameters
Param Type Details value (optional)Boolean
value to set, either
true
orfalse
. Default isfalse
. If omitted, it will return the current value.Returns
$httpBackend
Boolean
self when used as a setter, and the current value when used as a getter
-
whenGET(url, [headers], [keys]);
Creates a new backend definition for GET requests. For more info see
when()
.Parameters
Param Type Details url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current definition.
headers (optional)Object
function(Object)
HTTP headers or function that receives http header object and returns true if the headers match the current definition.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. -
whenHEAD(url, [headers], [keys]);
Creates a new backend definition for HEAD requests. For more info see
when()
.Parameters
Param Type Details url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current definition.
headers (optional)Object
function(Object)
HTTP headers or function that receives http header object and returns true if the headers match the current definition.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. -
whenDELETE(url, [headers], [keys]);
Creates a new backend definition for DELETE requests. For more info see
when()
.Parameters
Param Type Details url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current definition.
headers (optional)Object
function(Object)
HTTP headers or function that receives http header object and returns true if the headers match the current definition.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. -
whenPOST(url, [data], [headers], [keys]);
Creates a new backend definition for POST requests. For more info see
when()
.Parameters
Param Type Details url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current definition.
data (optional)string
RegExp
function(string)
HTTP request body or function that receives data string and returns true if the data is as expected.
headers (optional)Object
function(Object)
HTTP headers or function that receives http header object and returns true if the headers match the current definition.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. -
whenPUT(url, [data], [headers], [keys]);
Creates a new backend definition for PUT requests. For more info see
when()
.Parameters
Param Type Details url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current definition.
data (optional)string
RegExp
function(string)
HTTP request body or function that receives data string and returns true if the data is as expected.
headers (optional)Object
function(Object)
HTTP headers or function that receives http header object and returns true if the headers match the current definition.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. -
whenJSONP(url, [keys]);
Creates a new backend definition for JSONP requests. For more info see
when()
.Parameters
Param Type Details url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current definition.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. -
whenRoute(method, url);
Creates a new backend definition that compares only with the requested route.
Parameters
Param Type Details method string
HTTP method.
url string
HTTP url string that supports colon param matching.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. Seewhen
for more info. -
expect(method, url, [data], [headers], [keys]);
Creates a new request expectation.
Parameters
Param Type Details method string
HTTP method.
url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current definition.
data (optional)string
RegExp
function(string)
Object
HTTP request body or function that receives data string and returns true if the data is as expected, or Object if request body is in JSON format.
headers (optional)Object
function(Object)
HTTP headers or function that receives http header object and returns true if the headers match the current expectation.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled.- respond –
{function([status,] data[, headers, statusText]) | function(function(method, url, data, headers, params)}
– The respond method takes a set of static data to be returned or a function that can return an array containing response status (number), response data (Array|Object|string), response headers (Object), HTTP status text (string), and XMLHttpRequest status (string:complete
,error
,timeout
orabort
). The respond method returns therequestHandler
object for possible overrides.
- respond –
-
expectGET(url, [headers], [keys]);
Creates a new request expectation for GET requests. For more info see
expect()
.Parameters
Param Type Details url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current expectation.
headers (optional)Object
function(Object)
HTTP headers or function that receives http header object and returns true if the headers match the current expectation.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. See #expect for more info. -
expectHEAD(url, [headers], [keys]);
Creates a new request expectation for HEAD requests. For more info see
expect()
.Parameters
Param Type Details url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current expectation.
headers (optional)Object
function(Object)
HTTP headers or function that receives http header object and returns true if the headers match the current expectation.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. -
expectDELETE(url, [headers], [keys]);
Creates a new request expectation for DELETE requests. For more info see
expect()
.Parameters
Param Type Details url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current expectation.
headers (optional)Object
function(Object)
HTTP headers or function that receives http header object and returns true if the headers match the current expectation.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. -
expectPOST(url, [data], [headers], [keys]);
Creates a new request expectation for POST requests. For more info see
expect()
.Parameters
Param Type Details url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current expectation.
data (optional)string
RegExp
function(string)
Object
HTTP request body or function that receives data string and returns true if the data is as expected, or Object if request body is in JSON format.
headers (optional)Object
function(Object)
HTTP headers or function that receives http header object and returns true if the headers match the current expectation.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. -
expectPUT(url, [data], [headers], [keys]);
Creates a new request expectation for PUT requests. For more info see
expect()
.Parameters
Param Type Details url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current expectation.
data (optional)string
RegExp
function(string)
Object
HTTP request body or function that receives data string and returns true if the data is as expected, or Object if request body is in JSON format.
headers (optional)Object
function(Object)
HTTP headers or function that receives http header object and returns true if the headers match the current expectation.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. -
expectPATCH(url, [data], [headers], [keys]);
Creates a new request expectation for PATCH requests. For more info see
expect()
.Parameters
Param Type Details url string
RegExp
function(string)=
HTTP url or function that receives a url and returns true if the url matches the current expectation.
data (optional)string
RegExp
function(string)
Object
HTTP request body or function that receives data string and returns true if the data is as expected, or Object if request body is in JSON format.
headers (optional)Object
function(Object)
HTTP headers or function that receives http header object and returns true if the headers match the current expectation.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. -
expectJSONP(url, [keys]);
Creates a new request expectation for JSONP requests. For more info see
expect()
.Parameters
Param Type Details url string
RegExp
function(string)=
HTTP url or function that receives an url and returns true if the url matches the current expectation.
keys (optional)Array
Array of keys to assign to regex matches in request url described above.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. -
expectRoute(method, url);
Creates a new request expectation that compares only with the requested route.
Parameters
Param Type Details method string
HTTP method.
url string
HTTP url string that supports colon param matching.
Returns
requestHandler
Returns an object with
respond
method that controls how a matched request is handled. You can save this object for later use and invokerespond
again in order to change how a matched request is handled. Seeexpect
for more info. -
flush([count], [skip]);
Flushes pending requests using the trained responses. Requests are flushed in the order they were made, but it is also possible to skip one or more requests (for example to have them flushed later). This is useful for simulating scenarios where responses arrive from the server in any order.
If there are no pending requests to flush when the method is called, an exception is thrown (as this is typically a sign of programming error).
Parameters
Param Type Details count (optional)number
Number of responses to flush. If undefined/null, all pending requests (starting after
skip
) will be flushed.skip (optional)number
Number of pending requests to skip. For example, a value of
5
would skip the first 5 pending requests and start flushing from the 6th onwards.(default: 0)
-
verifyNoOutstandingExpectation();
Verifies that all of the requests defined via the
expect
api were made. If any of the requests were not made, verifyNoOutstandingExpectation throws an exception.Typically, you would call this method following each test case that asserts requests using an "afterEach" clause.
afterEach($httpBackend.verifyNoOutstandingExpectation);
-
verifyNoOutstandingRequest();
Verifies that there are no outstanding requests that need to be flushed.
Typically, you would call this method following each test case that asserts requests using an "afterEach" clause.
afterEach($httpBackend.verifyNoOutstandingRequest);
-
resetExpectations();
Resets all request expectations, but preserves all backend definitions. Typically, you would call resetExpectations during a multiple-phase test when you want to reuse the same instance of $httpBackend mock.
© 2010–2018 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.7.8/docs/api/ngMock/service/$httpBackend