В настоящее время мы пытаемся протестировать наши службы angular, которые используют обещания для возврата значений контроллерам. Проблема в том, что функции, которые мы присоединяем к .then, не вызываются в Jasmine.
Мы обнаружили, что добавление $rootScope.digest() в функцию после возврата промиса позволяет вызывать синхронные промисы, однако это по-прежнему не работает для асинхронных промисов.
Код до сих пор
beforeEach(inject(function (Service, $rootScope)
{
service = Service;
root = $rootScope;
}));
it('gets all the available products', function (done)
{
service.getData().then(function (data)
{
expect(data).not.toBeNull();
expect(data.length).toBeGreaterThan(0);
done();
});
root.$digest();
});
В этом случае промис вызывается нормально, но если он асинхронный, он не будет вызван, потому что промис не готов к "перевариванию" к моменту вызова root.$digest().
Есть ли способ узнать, когда обещание после разрешения, чтобы я мог вызвать дайджест? Или, может быть, что-то, что сделает это автоматически? Спасибо ;)
Часть службы, которую мы должны протестировать (обработка ошибок удалена):
var app = angular.module('service', []);
/**
* Service for accessing data relating to the updates/downloads
* */
app.factory('Service', function ($q)
{
... init
function getData()
{
var deffered = $q.defer();
var processors = [displayNameProc];
downloads.getData(function (err, data)
{
chain.process(processors, data, function (err, processedData)
{
deffered.resolve(processedData);
});
});
return deffered.promise;
}
...
В случае, когда возникает проблема, когда service.getData является асинхронным, обещание разрешается, но функция, прикрепленная к этому обещанию из тестового кода, не вызывается, потому что root.$digest уже был вызван. Надеюсь, это даст больше информации
Временное решение
var interval;
beforeEach(inject(function ($rootScope)
{
if(!interval)
{
interval = function ()
{
$rootScope.$digest();
};
window.setInterval(interval, /*timing*/);
}
}));
В итоге я использовал обходной путь, описанный выше, для многократного вызова дайджеста, чтобы каждый слой обещания имел возможность работать... это не идеально и не красиво, но для теста работает...