I am currently utilizing the $httpBackend
service within the ngMock module to emulate a GET request. The following is a sample controller code snippet sourced from the AngularJS documentation:
// Example controller code
function MyController($scope, $http) {
var authToken;
$http.get('/auth.py').success(function(data, status, headers) {
authToken = headers('A-Token');
$scope.user = data;
});
$scope.saveMessage = function(message) {
var headers = { 'Authorization': authToken };
$scope.status = 'Saving...';
$http.post('/add-msg.py', message, { headers: headers } ).success(function(response) {
$scope.status = '';
}).error(function() {
$scope.status = 'ERROR!';
});
};
}
Furthermore, here is the corresponding Jasmine test specification:
// Controller testing
describe('MyController', function() {
var $httpBackend, $rootScope, createController;
beforeEach(inject(function($injector) {
// Configuring mock http service responses
$httpBackend = $injector.get('$httpBackend');
// Universal backend definition for all tests
$httpBackend.when('GET', '/auth.py').respond({userId: 'userX'}, {'A-Token': 'xxx'});
// Obtaining a scope (the root scope)
$rootScope = $injector.get('$rootScope');
// Utilizing the $controller service to instantiate controllers
var $controller = $injector.get('$controller');
createController = function() {
return $controller('MyController', {'$scope' : $rootScope });
};
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should retrieve authentication token', function() {
$httpBackend.expectGET('/auth.py');
var controller = createController();
$httpBackend.flush();
});
it('should send message to server', function() {
var controller = createController();
$httpBackend.flush();
// Authentication is no longer relevant, but the controller will still transmit the request
// $httpBackend will respond without requiring the expectation and response to be specified
$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 include auth header', function() {
var controller = createController();
$httpBackend.flush();
$httpBackend.expectPOST('/add-msg.py', undefined, function(headers) {
// Verification of header transmission, failure to send will result in test failure
return headers['Authorization'] == 'xxx';
}).respond(201, '');
$rootScope.saveMessage('whatever');
$httpBackend.flush();
});
});
As outlined above, the mock request responds immediately during test execution. I am interested in introducing a delay to the mock GET request. Is there a method to achieve this? It seems that the $timeout
service may be necessary to accomplish this.
Extra Query: Are there any disadvantages to implementing a delay like this? Is this a reasonable practice for an AngularJS unit test?