Недавно я обновил свое приложение с Angular 1.5 до 1.6.3 и начал получать сбои модульного теста Jasmine (с PhantomJS) вокруг кода, основанного на обещаниях, который я написал:
Возможно необработанное отклонение: брошено undefined
Читая вокруг, я вижу, что принятое решение - связать .then () с блоками .catch (), чтобы изящно обрабатывать отклонения.
Я сделал это для одного из моих исходных файлов, который я тестирую, чтобы доказать, что это устраняет ошибку, которую он делает.
Однако теперь он обнаружил дополнительную проблему, когда ожидание, которое я тестирую, когда в моем коде вызывается отклонение обещания, больше не выполняется.
Это функция, которую я пытаюсь протестировать (после добавления необходимых блоков catch)
public deleteSomething = (thing) => {
return this.UserMessages.buildConfirmDialog().then(() => {
this.someService.remove(thing)
.then(() => {
this.UserMessages.showToast('Something deleted');
})
.catch((error) => {
//handle error
});
})
.catch((error) => {
//handle error
});
}
А вот и тест:
var thing = {foo: 'bar'},
deferredRemove,
deferredConfirm,
//Mock service below injected into controller later on before test are run
UserMessages = {
buildConfirmDialog: jasmine.createSpy('buildConfirmDialog').and.callFake(function() {
deferredConfirm = $q.defer();
return deferredConfirm.promise.catch(angular.noop);
})
};
//Inject and controller setup here...
describe('When deleting something', function() {
beforeEach(function() {
deferredRemove = $q.defer();
spyOn(someService, 'remove').and.returnValue(deferredRemove.promise.catch(angular.noop));
});
describe('and the user confirms the deletion', function() {
beforeEach(function() {
ctrl.deleteSomething(thing);
deferredConfirm.resolve();
deferredRemove.resolve();
$rootScope.$apply();
});
it('should call remove on someService', function() {
console.log('someService.remove.calls = ' + someService.remove.calls.count());
expect(someService.remove).toHaveBeenCalled();
});
});
describe('and the user cancels the deletion', function() {
beforeEach(function() {
someService.remove.calls.reset();
vm.deleteSomething(thing);
deferredConfirm.reject({});
$rootScope.$apply();
});
it('should not call remove on someService', function() {
console.log('someService.remove.calls = ' + someService.remove.calls.count());
expect(someService.remove.calls.count()).toEqual(0);
});
});
});
У меня не было .catch(angular.noop)
частей до обновления до 1.6.3, и я наткнулся на несколько сообщений, предлагающих сделать это, чтобы сделать тесты счастливыми, что, безусловно, помогло мне преодолеть необработанную ошибку отклонения в моем тестовом прогоне.
Проблема, с которой я сейчас сталкиваюсь, заключается в том, что для спецификации теста отклонения в моей службе не должно быть вызовов функции удаления, поэтому количество вызовов должно быть равно нулю, но оно продолжает выходить как 1. Я добавил строку чтобы сбросить вызовы в моем тесте, чтобы убедиться, что это не участвовало в предыдущем тесте (я знаю, что вызовы предназначены для сброса между тестами).
Этот тест работал нормально, когда я был на 1.5, так что это должно быть что-то из-за того, что мой код \ тест написан не так хорошо, как изменения в 1.6.x
Кто-нибудь может пролить свет на то, что здесь может происходить, пожалуйста?
Спасибо