ember интегрированный тест. иметь дело с асинхронными побочными эффектами
Я пробую пакет интеграционного тестирования ember ( http://emberjs.com/guides/testing/integration/), но получаю эту ошибку
Assertion Failed: You have turned on testing mode, which disabled the run-loop's autorun.
You will need to wrap any code with asynchronous side-effects in an Ember.run
Я сделал JSBin для воспроизведения этой ошибки: http://jsbin.com/InONiLe/9, которую мы можем увидеть, открыв консоль браузера.
Я считаю, что причиной этой ошибки является линия data.set('isLoaded', true);
в load()
метод App.Posts
, (Ссылка на код: http://jsbin.com/InONiLe/9/edit)
Теперь, если я заверну data.set('isLoaded', true);
линия в Ember.run()
, тогда он будет работать как положено и тест пройдет.
Тем не менее, я использую этот шаблон для многих моих моделей, и я не хочу просто обернуть каждый .set()
с Ember.run()
(переходы также вызывают ту же ошибку). Я также не хочу менять код приложения, чтобы тест работал.
Есть ли что-то еще, что я могу сделать, чтобы исправить ошибку?
Примечание. Я намеренно не возвращаю обещание в хуке модели, потому что в противном случае пользовательский интерфейс блокируется, пока обещание не будет разрешено. Я хочу, чтобы переход к маршруту произошел немедленно, чтобы я мог отобразить загрузочный счетчик.
1 ответ
Когда вы используете некоторые методы, запускающие асинхронный код, такие как ajax, setInterval, indexeddb api и т. Д. Вам нужно будет делегировать разрешенные обратные вызовы этих методов для Ember.run
, поэтому ember поставит эти операции в очередь в очередь выполнения и обеспечит синхронизацию приложения. Таким образом, изменение вашего кода для этого является правильным способом справиться с этим:
App.Posts = Ember.Object.create({
load: function() {
return new Ember.RSVP.Promise(function(resolve, reject) {
var data = Ember.Object.create();
$.ajax({
url: 'https://api.github.com/users/octocat/orgs'
}).then(function() {
data.set('isLoaded', true);
Ember.run(null, resolve, data);
}, reject);
});
}
});
Другой совет всегда использовать Ember.RSVP.Promise
потому что более совместим с Ember, чем $.Defered
, $.Deferred возвращается $.ajax
,
Вот обновленный jsbin http://jsbin.com/InONiLe/10/edit
ОБНОВИТЬ
Потому что в вашем случае вы не хотите возвращать обещание, просто отбросьте его и просто верните сами данные:
App.Posts = Ember.Object.create({
load: function() {
var data = Ember.Object.create();
$.ajax({
url: 'https://api.github.com/users/octocat/orgs'
}).then(function() {
Ember.run(function() {
data.set('isLoaded', true);
});
}, function(xhr) {
Ember.run(function() {
// if using some ember stuff put here
});
});
return data;
}
});
Вот jsbin, показывающий эту работу http://jsbin.com/InONiLe/17/edit
Я надеюсь, что это помогает