Ember并发超时挂在qunit中 [英] Ember concurrency timeout hanging in qunit

查看:61
本文介绍了Ember并发超时挂在qunit中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Ember中,我有一个组件可以启动永无休止的轮询,以使某些数据保持最新状态.像这样:

In Ember I have a component that starts a never-ending poll to keep some data up to date. Like so:

export default Component.extend({
  pollTask: task(function * () {
    while(true) {
      yield timeout(this.get('pollRate'));
      this.fetchSomeData();
    }
  }).on('init')
})

这将导致预先存在的验收测试陷入该任务并永久运行,即使它应该异步运行也是如此.测试看起来像这样:

This causes a preexisting acceptance test to get stuck in this task and run forever, even though it should be run asynchronously. The test looks like this:

test('my test', async function(assert) {
  mockFindRecord(make('fetched-model'));

  await visit('/mypage'); // gets stuck here
  await typeIn('input', 'abc123');

  assert.ok(somethingAboutThePage);
});

起初我以为我对请求的嘲笑是错误的,并且测试只是在超时,但实际上是在正确轮询数据.删除此任务可使验收测试正常完成.

I thought at first that I had mocked the request wrong and that the test was just timing out, but it was in fact correctly polling data. Removing this task makes the acceptance test finish normally.

手动测试此方法似乎可以正常工作,并且不会卡住任何东西.为什么会发生这种情况?解决此问题的正确方法是什么?

Testing this manually seems to work fine, and nothing gets stuck. Why is this happening and what is the right way to address this?

看到了单元测试余烬并发任务和收益,但是并没有真正的帮助,因为它仅处理单元测试.

Saw Unit testing ember-concurrency tasks and yields but it doesn't really help since it only deals with unit tests.

推荐答案

您没有做错什么,这是ember-concurrency的常见陷阱.Ember-concurrency的 timeout()函数依靠 Ember.run.later()来创建超时,幸运的是,Ember的测试套件知道使用 Ember.run.later()并等待所有计时器稳定下来,然后再继续测试.由于您的代码正在使用无限循环,因此您的计时器永远不会稳定下来,因此测试将挂起.Ember指南

You're not doing anything wrong and this is a common gotcha with ember-concurrency. Ember-concurrency's timeout() function relies on Ember.run.later() to create the timeout and fortunately or unfortunately, Ember's test suite is aware of all timers created with Ember.run.later() and will wait for all timers to settle before letting the test continue. Since your code is using an infinite loop your timers will never settle so the test hangs. There's a nice little section about testing asynchronous code in the Ember guides here.

在ember-concurrency文档中有一个关于此确切问题的部分此处.我建议您仔细阅读一下,以了解他们对如何解决此问题的建议,尽管当时似乎似乎没有真正的优雅解决方案.

There's a section in the ember-concurrency docs about this exact problem here. I recommend you look through it to see their recommendations on how to tackle this although it seems as if there's no real elegant solution at the time.

使此应用程序不挂起的最快,最简单的方法就是检查应用程序是否正在测试(很糟糕,我知道):

The quickest and probably easiest way to get this to not hang would be to throw in a check to see if the app is being tested (gross, I know):

pollTask: task(function * () {
    while(true) {
      yield timeout(this.get('pollRate'));
      this.fetchSomeData();
      if (Ember.testing) return; // stop polling to prevent tests from hanging
    }
  }).on('init')

您还可以尝试在 tests/helpers/start-app.js 文件中引发对 Ember.run.cancelTimers()的调用(另一建议是该部分):

You can also try to throw in a call to Ember.run.cancelTimers() in your tests/helpers/start-app.js file (another suggestion in that section):

window._breakTimerLoopsId = Ember.run.later(() => {
  Ember.run.cancelTimers();
}, 500);

但是它似乎没有出现在API文档中,所以我个人不会依赖它.

But it doesn't seem to appear in the API docs so I personally wouldn't rely on it.

这篇关于Ember并发超时挂在qunit中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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