问题
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