Я хочу иметь функцию, которая возвращает обещание, которое разрешается при загрузке DOM:
function waitForDom() {
return $q((resolve) => {
$window.addEventListener('DOMContentLoaded', () => {
resolve("yay, i've loaded");
});
})
})
Это прекрасно работает в браузере. Однако, когда я пытаюсь его протестировать, тест никогда не завершается, так как это обещание никогда не разрешается:
it('some test', (done) => inject(($window, $q, $rootScope) => {
waitForDom()
.then(it => expect(it).toBe("yay, i've loaded"))
.then(done);
$rootScope.$digest();
}));
Из того, что я понимаю в angular, обещания не разрешаются (и не связываются), пока вы не вызовете $digest
. Это позволяет тестировать angular синхронно. Я понимаю. Однако пример, который у меня здесь, должен завершиться, но по какой-то причине он всегда истекает.
Я пытался поместить resolve()
внутрь $scope.$apply()
, но получаю сообщение "$digest уже выполняется".
Я попытался поместить $digest
внутрь setTimeout
, и это дало мне $digest, который уже выполняется, что меня действительно смущает. Но проблема не в этом.
TLDR Как добиться завершения теста?
Изменить
Хотя я могу обойти приведенный выше пример, я ищу общее решение, когда вы разрешаете обещание внутри тела прослушивателя событий DOM, например:
function appendIframe() {
return $q((resolve) => {
const iframe = $window.document.createElement('iframe');
const iframeParent = $window.document.body;
iframe.src = authUrl;
iframe.onload = function() {
resolve('iframe loaded')
};
iframeParent.appendChild(iframe);
});
})
И нет, делать это с jqlite не имеет значения.
DOMContentLoaded
действительно срабатывает, когда вы запускаете тест? - person JLRishe   schedule 15.12.2017