Приемочное тестирование Ember - ошибка асинхронных побочных эффектов

Попытка провести приемочные испытания в Ember:

test('successful login', (assert) => {

  Ember.run(() => {
    visit('/signin');
    fillIn('#email', 'validemail@server.com');
    fillIn('#password', 'password');
    click(':submit');

    andThen(function() {
      assert.equal(currentURL(), '/');
    });
  });
});

Изредка (и, казалось бы, случайно) выдает ошибку:

"Глобальная ошибка: Ошибка: Утверждение не выполнено: вы включили режим тестирования, который отключил автозапуск цикла выполнения. При запуске нужно будет обернуть любой код асинхронными побочными эффектами..."

Я смог получить рабочую версию:

test('successful login', (assert) => {
  const done = assert.async();

  Ember.run(() => {
    visit('/signin').then(() => {
      fillIn('#email', 'isaac@silverorange.com').then(() => {
        fillIn('#password', 'keen').then(() => {
          click(':submit').then(() => {
            assert.equal(currentURL(), '/');
            done();
          });
        });
      });
    });
  });
});

Однако, если я включаю второй тест, использующий тот же маршрут (для неудачного входа в систему), один из них почти всегда заканчивается ошибкой, перечисленной выше.

Мне интересно, что я не понимаю о цикле выполнения Ember.run и о том, как тестировать с асинхронным поведением. Любая помощь или указатели на хороший ресурс будет принята с благодарностью!

2 ответа

Согласно руководству, ваш код должен быть таким:

test('successful login', (assert) => {
  visit('/signin');
  fillIn('#email', 'validemail@server.com');
  fillIn('#password', 'password');
  click(':submit');

  andThen(function() {
    assert.equal(currentURL(), '/');
  });
});

Вам не нужно добавлять Ember.run в ваших случаях.

Чаще всего эта проблема возникает, когда вы делаете (асинхронно) что-то в вашем приложении, которое не упаковано должным образом для Ember (под упаковкой я подразумеваю выполнение внутри цикла выполнения Ember).

Наиболее распространенные причины

  1. Вы подключили обработчик событий к DOM, либо напрямую, либо с помощью jQuery, не включая взаимодействие с приложением Ember в Ember.run()
  2. Вы выполнили XHR (асинхронный), либо напрямую, либо с помощью jQuery, не включая взаимодействие с приложением Ember внутри обратного вызова в Ember.run()

Общее исправление

Когда вы вызываете выполнение кода, которое взаимодействует с вашим приложением вне runloop (обратный вызов XHR или обработчики событий), оберните этот код Ember.run().

События:

Ember.$('div').on('mouseover',function() {
    Ember.run(function() {
       // Interaction with application
    });
});

XHR / Ajax:

Ember.$.ajax({
    success: function() {
        Ember.run(function() {
           // Interaction with application
        });
    }
});

Лучшие практики

  1. При работе с событиями DOM:
  2. Когда вы хотите сделать AJAX/XHR, используйте ember-ajax ( https://github.com/ember-cli/ember-ajax)
Другие вопросы по тегам