ember integration test error. dealing with asynchronous side-effects

放肆的年华 提交于 2020-01-05 07:51:00

问题


I'm trying ember's integration testing package (http://emberjs.com/guides/testing/integration/) but I am getting this error

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

I've made a JSBin to reproduce this error: http://jsbin.com/InONiLe/9, which we can see by opening up the browser's console.

I believe what's causing this error is the line data.set('isLoaded', true); in the load() method of App.Posts. (Link to code: http://jsbin.com/InONiLe/9/edit)

Now, if I wrap the data.set('isLoaded', true); line in an Ember.run(), then it will work as expected and the test will pass.

However, I am using this pattern for a lot of my models and I don't want to just wrap every .set() with an Ember.run() (transitions also trigger the same error). I also don't want to change application code for the sake of making the test work.

Is there something else I can do to fix the error?

Note: I am purposely not returning a promise in the model hook because otherwise the UI is blocked until the promise is resolved. I want the transition to the route to happen immediately so that I can display a loading spinner.


回答1:


When you use some methods, that triggers async code, like ajax, setInterval, the indexeddb api etc. You will need to delegate the resolved callbacks of theses methods to Ember.run, so ember will queue these operations in your runloop and it ensure that application is in sync. So changing your code for this is the correct way to handle this:

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

Other advise is to always use the Ember.RSVP.Promise, because is more compatible with Ember than $.Defered. $.Deferred is returned by $.ajax.

Here is an updated jsbin http://jsbin.com/InONiLe/10/edit

UPDATE

Because in your case you don't want to return a promise, so just drop it, and just return the data itself:

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

Here is the jsbin showing this working http://jsbin.com/InONiLe/17/edit

I hope it helps



来源:https://stackoverflow.com/questions/18664505/ember-integration-test-error-dealing-with-asynchronous-side-effects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!