Действия модульного тестирования в контроллере ember, которые возвращают обещания
У меня есть контроллер, который выполняет асинхронную операцию, которую я хотел бы проверить:
/*globals Ember, momnent*/
import { raw as icAjaxRaw } from 'ic-ajax';
//...
actions: {
foo: function() {
var req = icAjaxRaw({
type: 'POST',
url: ApiUtils.apiUrl+'/dofoo',
processData: false,
});
return req.then(
function resolve(result) {
console.log(result.response);
this.set('fooLastDoneAt', moment());
}.bind(this)
);
},
... и в тестах:
test('actions.foo', function() {
expect(2);
var ctrl = this.subject();
var model = {
fooLastDoneAt: moment().add(-10, 'days'),
};
ctrl.set('model', model);
ok(ctrl.get('fooLastDoneAt').isBefore(moment().add(-1, 'days')), true, 'initial');
ctrl.send('foo');
ok(ctrl.get('fooLastDoneAt').isBefore(moment().add(-1, 'days')), false, 'updated date');
});
Однако это неизбежно приводит к возникновению ошибки в другом, не связанном тестовом примере:
"Uncaught Error: Assertion Failed: calling set on destroyed object"[
что должно происходить, потому что this.set('fooLastDoneAt', moment());
выполняется после того, как этот тестовый пример завершен, и тестовый исполнитель сделал teardown
для этого модуля и перешел к следующему; пока действие еще выполняется.
Могу ли я дождаться асинхронного завершения действия, прежде чем перейти к следующему шагу модульного теста?
@ kingpin2k предлагает это решение, в котором вы передаете обещанный отложенный объект в действие. Тем не менее, в моем приложении само приложение никогда бы этого не сделало, и это кажется фундаментальной проблемой, если мне нужно изменить исходный код приложения, чтобы он мог быть протестирован - особенно потому, что он добавляет дополнительную сложность.
Существуют ли другие способы заставить выполнение теста ждать завершения действия?
1 ответ
Я бы пошел на QUnit
start()
stop()
функции.
Вот пример использования взятый из документации QUnit:
QUnit.test( "a test", function( assert ) {
QUnit.stop();
asyncOp();
setTimeout(function() {
assert.equals( asyncOp.result, "someExpectedValue" );
QUnit.start();
}, 150 );
});
Также библиотека ember-qunit покрывает это then
,
Вот пример для ember-qunit
test('actions.foo', function() {
expect(2);
var ctrl = this.subject();
var model = {
fooLastDoneAt: moment().add(-10, 'days'),
};
ctrl.set('model', model);
ok(ctrl.get('fooLastDoneAt').isBefore(moment().add(-1, 'days')), true, 'initial');
ctrl.send('foo').then(function(){
ok(ctrl.get('fooLastDoneAt').isBefore(moment().add(-1, 'days')), false, 'updated date');
});
});
Я не тестировал код, поэтому надеюсь, что он решит вашу проблему