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

Я надеюсь, что это помогает

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