In AngularJS, $http
is commonly used for making API calls. When testing, it’s crucial to mock HTTP requests to prevent actual API calls. AngularJS provides $httpBackend
to intercept and mock $http
calls.
This guide covers:
- What is
$httpBackend
? - Setting Up Karma and Jasmine for Testing
- Mocking GET Requests
- Mocking POST Requests
- Handling Errors and Edge Cases
- Best Practices
- Running Tests
1. What is $httpBackend
?
$httpBackend
is an AngularJS service that intercepts $http
calls and allows us to: ✔ Mock API responses.
✔ Simulate success and failure scenarios.
✔ Test API-dependent components without calling real servers.
2. Setting Up Karma and Jasmine
Ensure you have Karma and Jasmine installed:
npm install karma karma-jasmine jasmine-core karma-chrome-launcher angular-mocks --save-dev
In karma.conf.js
, include angular-mocks:
files: [
'node_modules/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
'app.js',
'services/*.js',
'controllers/*.js',
'tests/**/*.spec.js'
]
3. Mocking GET Requests
Example: UserService (userService.js
)
app.service('UserService', function($http) {
this.getUser = function() {
return $http.get('/api/user');
};
});
Test Case for GET Request (userService.spec.js
)
describe('UserService', function() {
var UserService, $httpBackend;
beforeEach(module('myApp'));
beforeEach(inject(function(_UserService_, _$httpBackend_) {
UserService = _UserService_;
$httpBackend = _$httpBackend_;
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should fetch user data successfully', function() {
var mockUser = { id: 1, name: "John Doe" };
$httpBackend.expectGET('/api/user').respond(200, mockUser);
var result;
UserService.getUser().then(function(response) {
result = response.data;
});
$httpBackend.flush(); // Triggers the mock response
expect(result).toEqual(mockUser);
});
});
Explanation:
$httpBackend.expectGET('/api/user').respond(200, mockUser);
→ Mocks GET request.$httpBackend.flush();
→ Triggers the response.expect(result).toEqual(mockUser);
→ Ensures response data matches mock.
4. Mocking POST Requests
Example: Authentication Service (authService.js
)
app.service('AuthService', function($http) {
this.login = function(credentials) {
return $http.post('/api/login', credentials);
};
});
Test Case for POST Request (authService.spec.js
)
describe('AuthService', function() {
var AuthService, $httpBackend;
beforeEach(module('myApp'));
beforeEach(inject(function(_AuthService_, _$httpBackend_) {
AuthService = _AuthService_;
$httpBackend = _$httpBackend_;
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should authenticate user successfully', function() {
var credentials = { username: "admin", password: "password" };
var mockResponse = { token: "abcd1234" };
$httpBackend.expectPOST('/api/login', credentials).respond(200, mockResponse);
var result;
AuthService.login(credentials).then(function(response) {
result = response.data;
});
$httpBackend.flush(); // Simulates response
expect(result).toEqual(mockResponse);
});
});
Key Points:
$httpBackend.expectPOST('/api/login', credentials).respond(200, mockResponse);
→ Mocks POST request.- Ensures correct request body and response.
- Uses
$httpBackend.flush()
to trigger the response.
5. Handling Errors and Edge Cases
To test error handling, modify the AuthService
:
app.service('AuthService', function($http) {
this.login = function(credentials) {
return $http.post('/api/login', credentials)
.catch(function(error) {
return error;
});
};
});
Test Case for Failed Authentication
it('should handle authentication failure', function() {
var credentials = { username: "admin", password: "wrongpass" };
var mockError = { message: "Invalid Credentials" };
$httpBackend.expectPOST('/api/login', credentials).respond(401, mockError);
var result;
AuthService.login(credentials).then(function(response) {
result = response;
});
$httpBackend.flush();
expect(result.status).toBe(401);
expect(result.data).toEqual(mockError);
});
Handling Network Errors
it('should handle network error', function() {
$httpBackend.expectGET('/api/user').respond(-1); // Simulating network failure
var result;
UserService.getUser().catch(function(error) {
result = error;
});
$httpBackend.flush();
expect(result.status).toBe(-1);
});
6. Best Practices
✔ Use verifyNoOutstandingExpectation()
and verifyNoOutstandingRequest()
to clean up mock requests.
✔ Always call $httpBackend.flush()
to trigger responses.
✔ Use respond(-1)
to simulate network failures.
✔ Keep tests isolated. Each test should work independently.
✔ Use .catch()
in service methods to handle HTTP errors gracefully.