Приемочное тестирование 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).
Наиболее распространенные причины
- Вы подключили обработчик событий к DOM, либо напрямую, либо с помощью jQuery, не включая взаимодействие с приложением Ember в Ember.run()
- Вы выполнили 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
});
}
});
Лучшие практики
- При работе с событиями DOM:
- Использовать обработку событий компонента ( https://guides.emberjs.com/v2.11.0/components/handling-events/)
- Используйте шаблонные действия ( https://guides.emberjs.com/v2.11.0/templates/actions/)
- Когда вы хотите сделать AJAX/XHR, используйте ember-ajax ( https://github.com/ember-cli/ember-ajax)