在 Ember 中,我有一个组件可以启动永无止境的轮询,以保持一些数据最新。就像这样:
export default Component.extend({
pollTask: task(function * () {
while(true) {
yield timeout(this.get('pollRate'));
this.fetchSomeData();
}
}).on('init')
})
这会导致预先存在的验收测试陷入此任务并永远运行,即使它应该异步运行。测试看起来像这样:
test('my test', async function(assert) {
mockFindRecord(make('fetched-model'));
await visit('/mypage'); // gets stuck here
await typeIn('input', 'abc123');
assert.ok(somethingAboutThePage);
});
我一开始以为我错误地模拟了请求,测试只是超时了,但实际上它正确地轮询了数据。删除该任务使验收测试正常完成。
手动测试似乎工作正常,并且没有任何卡住。为什么会发生这种情况以及解决此问题的正确方法是什么?
Saw 对 ember 并发任务和产量进行单元测试 https://stackoverflow.com/questions/58452244/unit-testing-ember-concurrency-tasks-and-yields但它并没有真正的帮助,因为它只处理单元测试。
你没有做错任何事,这是 ember 并发的常见问题。 Ember 并发timeout()
函数依赖于Ember.run.later()
创建超时,幸运的是或不幸的是,Ember 的测试套件知道使用以下命令创建的所有计时器Ember.run.later()
并等待所有计时器稳定后再继续测试。由于您的代码使用无限循环,您的计时器永远不会稳定,因此测试挂起。 Ember 指南中有一个关于测试异步代码的精彩小节here https://guides.emberjs.com/release/testing/testing-components/#toc_waiting-on-asynchronous-behavior.
ember-concurrency 文档中有一个关于这个确切问题的部分here http://ember-concurrency.com/docs/testing-debugging/。我建议你仔细阅读一下他们关于如何解决这个问题的建议,尽管当时似乎没有真正优雅的解决方案。
让它不挂起的最快且可能最简单的方法是检查应用程序是否正在测试(我知道,很糟糕):
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')
您还可以尝试拨打电话Ember.run.cancelTimers()
在你的tests/helpers/start-app.js
文件(该部分的另一个建议):
window._breakTimerLoopsId = Ember.run.later(() => {
Ember.run.cancelTimers();
}, 500);
但它似乎没有出现在 API 文档中,所以我个人不会依赖它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)