Ember Octane: модульное тестирование асинхронного действия на контроллере
Имея следующий контроллер и тесты:
приложение / контроллеры /application.js
import Controller from '@ember/controller';
import { action } from '@ember/object';
export default class ApplicationController extends Controller {
flag = false;
@action
raiseFlag() {
this.flag = true;
}
@action
async raiseFlagAsync() {
await new Promise(resolve => setTimeout(resolve, 1000));
this.flag = true;
}
}
тесты / модуль / контроллеры / приложение-test.js
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Controller | application', function(hooks) {
setupTest(hooks);
test('it raises flag', function(assert) {
let controller = this.owner.lookup('controller:application');
assert.equal(controller.flag, false);
controller.send('raiseFlag');
assert.equal(controller.flag, true);
});
test('it raises flag asyncronously', async function(assert) {
let controller = this.owner.lookup('controller:application');
assert.equal(controller.flag, false);
await controller.send('raiseFlagAsync');
assert.equal(controller.flag, true);
});
});
Первый тестовый пример пройден. Второй тестовый пример не выполняется (асинхронный)
Каков способ ожидания асинхронного действия с помощью октанового угля?
2 ответа
Решение
Уловка здесь в том, чтобы не использовать send
! Обычно я бы использовалsend
только если вам нужно пузыри действий в цепочке маршрутов. Это немного старая концепция, и она не имеет возвращаемого значения. Такawait controller.send
работать не будет.
Вам нужно просто вызвать действие напрямую:
test('it raises flag asyncronously', async function(assert) {
let controller = this.owner.lookup('controller:application');
assert.equal(controller.flag, false);
await controller.raiseFlagAsync();
assert.equal(controller.flag, true);
});
Не уверен, почему было так сложно найти эту информацию, возможно, плохой SEO.
import { waitUntil } from '@ember/test-helpers';
test('it raises flag asyncronously', async function(assert) {
let controller = this.owner.lookup('controller:application');
assert.equal(controller.flag, false);
controller.send('raiseFlagAsync');
await waitUntil(() => controller.flag === true);
});
Если кто-то придумает более тусклый ответ, я приму это однажды