Ember - 返回一个承诺,以前的模型不与Qunit一起工作 [英] Ember - Return a promise from beforeModel not working with Qunit

查看:96
本文介绍了Ember - 返回一个承诺,以前的模型不与Qunit一起工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 ApplicationRoute 中,我实现一个 beforeModel 钩子,执行服务器调用以查看是否存在有效的会话。如果是这样,那么应用程序将导航到仪表板路由,否则它将转到登录路由。我试图实现一些测试,我似乎无法让它与QUnit一起工作。我不断得到:

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:


断言失败:您已打开测试模式,禁用
运行循环的自动运行。您将需要在Ember.run中包含异步
副作用的任何代码

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

这是一个plunker http://plnkr.co/edit/e0Q4qz?p=preview 我已经模拟了一个服务器调用通过创建返回承诺并在几毫秒内执行方法的 doLater 方法。我可以让它工作的唯一方法是不要从 beforeModel 钩子返回承诺。我正在使用 App.deferReadiness() 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");
    });
  });
}


推荐答案

首先,添加示例是真棒,显示你尝试,并使它更容易调试。

First off, adding the example is awesome, shows you tried, and makes it so much easier to debug.

在你的情况下,没有必要提前准备,问题是setTimeout生活在运行循环,但Ember.run.later不工作也一样!

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/编辑/ lZKM4JBluQ27rcnfXlWS?p =预览

http://plnkr.co/edit/wFOCGQt3ahiuqi8el0rB?p=preview

这篇关于Ember - 返回一个承诺,以前的模型不与Qunit一起工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆