Я использую службу $httpBackend
в модуле ngMock для имитации запроса GET. Из AngularJS documentation, вот пример контроллера:Как смоделировать сетевую задержку при модульном тестировании контроллера AngularJS?
// The 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!';
});
};
}
и, вот соответствующий жасмин тест спецификации:
// testing controller
describe('MyController', function() {
var $httpBackend, $rootScope, createController;
beforeEach(inject(function($injector) {
// Set up the mock http service responses
$httpBackend = $injector.get('$httpBackend');
// backend definition common for all tests
$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 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 send, 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();
});
});
Как написано выше, фиктивный запрос мгновенно реагирует при выполнении тестов. Я хотел бы установить задержку в ложном запросе GET. Это возможно? У меня есть чувство, что для достижения этой цели понадобится услуга $timeout
.
Бонус Вопрос: Есть ли какие-либо недостатки в установке задержки как это? Это разумная вещь, чтобы сделать в модульном тесте AngularJS?
о бонусном вопросе: http://superuser.com/questions/330501/how-can-i-simulate-a-slow-connection-or-limit-the-bandwidth-that-firefox-can-us I не думайте, что это то, что вы хотите иметь в модульном тесте. –
@EduardGamonal: я буквально не хочу дросселировать браузер; должно быть достаточно углового 'window.setTimeout'. –
Да, вы можете использовать таймаут, но вы должны тестировать две вещи: небольшую полосу пропускания и высокую задержку. вы можете сделать это с помощью iprelay + firefox throttle. Я думаю, что модульные тесты предназначены для тестирования ввода/вывода компонентов, а не того, насколько надежно оно работает в суровых условиях сети. –