问题
In my ApplicationRoute
I implement a beforeModel
hook that does a server call to see if a valid session exists. If it does, then the app navigates to the 'dashboard' route, otherwise it goes to the 'login' route. I am trying to implement some tests and I can't seem to get it to work with QUnit. I keep getting:
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
Here is a plunker http://plnkr.co/edit/e0Q4qz?p=preview I have simulated a server call by creating a doLater
method that returns a promise and executes a method in a few milliseconds. The only way I can get it to work is to not return a promise from the beforeModel
hook. Am I using App.deferReadiness()
and Ember.run()
correctly?
App = Ember.Application.create({});
App.Router.map(function() {
this.resource('dashboard');
this.resource('login');
});
App.ApplicationRoute = Ember.Route.extend({
alreadyChecked: false,
beforeModel: function() {
var route = this;
// uncomment this line to stop this hook returning a promise
// return route.transitionTo(localStorage.user ? 'dashboard' : 'login');
if (!this.alreadyChecked) {
return doLater(function() {
// without the alreadyChecked flag, this function gets called twice
route.set('alreadyChecked', false);
route.transitionTo(localStorage.user ? 'dashboard' : 'login');
});
}
}
});
App.LoginRoute = Ember.Route.extend({
actions: {
login: function() {
var route = this;
doLater(function() {
localStorage.user = "Bill";
route.transitionTo('dashboard');
});
}
}
});
App.DashboardRoute = Ember.Route.extend({
actions: {
logout: function() {
var route = this;
doLater(function() {
localStorage.user = "";
route.transitionTo('login');
});
}
}
});
function doLater(fn) {
return Ember.RSVP.Promise(function(resolve, reject) {
setTimeout(function() {
resolve(fn());
}, 500);
});
}
// run the tests
if (true) { // toggle this boolean to run the app in testing mode
App.rootElement = '#ember-testing';
App.setupForTesting();
App.injectTestHelpers();
module('integration tests', {
setup: function() {
Ember.run(function() {
App.reset();
localStorage.user = "";
App.deferReadiness();
});
}
});
test('can navigate to login page', function() {
expect(1);
Ember.run(App, 'advanceReadiness');
visit("/login").then(function() {
ok(true, "Tests work");
});
});
}
回答1:
First off, adding the example is awesome, shows you tried, and makes it so much easier to debug.
In your case there is no need to advance readiness, and the problem is setTimeout lives outside of the run loop, but Ember.run.later doesn't and works the same!
http://plnkr.co/edit/lZKM4JBluQ27rcnfXlWS?p=preview
http://plnkr.co/edit/wFOCGQt3ahiuqi8el0rB?p=preview
来源:https://stackoverflow.com/questions/20602692/ember-return-a-promise-from-beforemodel-not-working-with-qunit