Ember - Return a promise from beforeModel not working with Qunit

守給你的承諾、 提交于 2019-12-21 18:42:29

问题


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

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