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);
});

Если кто-то придумает более тусклый ответ, я приму это однажды

Другие вопросы по тегам