Я пытаюсь написать модульный тест для службы AngularJS с Karma и Jasmine, используя браузер PhantomJS. Служба, которую я хочу протестировать, использует вложенные промисы (для чтения базы данных IndexedDB, получения ответов от сервера и записи ответа обратно в базу данных).
То же самое необходимо сделать при записи в базу данных (записать локальную базу данных, отправить/поместить на сервер, обновить локальную базу данных с помощью идентификатора сервера). Все тесты, которые я пишу, работают, кроме тестов на обработку потери соединения с сервером.
Когда это происходит, метод sync() устанавливает онлайн-статус в false и создает $timeout, который многократно проверяет наличие соединения, выполняя рекурсивный вызов. Если соединение снова установлено, все несинхронизированные данные будут синхронизированы (и промисы соответствующих вызовов sync() будут разрешены).
describe('Harmonized', function() {
var ... // setting all 'global' variables
[...]
beforeEach(function(){
// Address that the service sends a ping to check if online again
pingGet = backend.when('GET', 'http://localhost:2403');
pingGet.respond(0);
testTablePut121 = backend.when('PUT', 'http://localhost:2403/test_table/121');
testTablePut121.respond(function(method, url, data, headers) { ... } // returns 200
[...]
}
[...]
it('should try to sync a SAVED element but should fail because of missing server connectivity', function() {
var list;
var timeoutCounter = 0;
_checkOnline = harmonized._checkOnline; // harmonized is the service that has to be testet
harmonized._checkOnline = function () {
// only call the original function two times
if (timeoutCounter++ < 2) {
_checkOnline();
// flush the $timeout and the $httpBackend
timeout.flush(2000);
backend.flush(1);
// this also gives me an error because of the $digest already in progress
console.log('after tick');
}
};
all.getList().then(function(entries) {
list = entries;
testTablePut121.respond(0);
pingGet = backend.expect('GET', 'http://localhost:2403');
pingGet.respond(0);
spyOn(list[0], 'sync').and.callThrough();
list[0].save().then(
// resolve is called when the server call was successfull
function() {
expect(list[0]._synchronized).toBeTruthy();
expect(list[0].sync.calls.count()).toBe(2);
console.log('done');
},
// reject is called when the server response an error other than 0 (which is not the case in this test spec)
null,
// notify is called when the local db save is made
function(){
expect(list[0].sync.calls.count()).toBe(1);
expect(list[0]._synchronized).toBeFalsy();
});
backend.flush(1);
});
backend.flush(1);
});
Когда функция backend.flush() вызывается во второй раз (чтобы сбросить http-запрос, сделанный в функции save(), я получаю сообщение об ошибке, говорящее мне, что $digest уже выполняется. Пропустив строку, не сбрасывать запрос (и также получить ошибку из-за этого).
Есть ли способ сбросить все в нужное время, не получая ошибки $digest?