我正在尝试使用ember的集成测试包(http://emberjs.com/guides/testing/integration/),但我收到此错误
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
我已经制作了一个JSBin来重现这个错误:http://jsbin.com/InONiLe/9,我们可以通过打开浏览器的控制台看到它。
我认为导致此错误的原因是data.set('isLoaded', true);
load()
方法中的行App.Posts
。 (链接到代码:http://jsbin.com/InONiLe/9/edit)
现在,如果我将data.set('isLoaded', true);
行包裹在Ember.run()
中,那么它将按预期工作,测试将通过。
但是,我在很多模型中使用这种模式,我不想只用.set()
包裹每个Ember.run()
(转换也会触发相同的错误)。我也不想为了使测试工作而改变应用程序代码。
我还能采取其他措施来解决错误吗?
注意:我故意不在模型钩子中返回promise,否则UI将被阻塞,直到promise被解析。我希望立即过渡到路线,以便我可以显示加载微调器。
答案 0 :(得分:3)
当你使用某些方法时,会触发异步代码,比如ajax,setInterval,indexeddb api等。你需要将这些方法的已解析回调委托给Ember.run
,这样ember会将这些操作排入你的队列中runloop并确保应用程序同步。因此,更改代码是正确的处理方法:
App.Posts = Ember.Object.create({
load: function() {
return new Ember.RSVP.Promise(function(resolve, reject) {
var data = Ember.Object.create();
$.ajax({
url: 'https://api.github.com/users/octocat/orgs'
}).then(function() {
data.set('isLoaded', true);
Ember.run(null, resolve, data);
}, reject);
});
}
});
其他建议是始终使用Ember.RSVP.Promise
,因为与Ember的兼容性高于$.Defered
。 $ .Deferred由$.ajax
返回。
这是更新的jsbin http://jsbin.com/InONiLe/10/edit
<强>更新强>
因为在您的情况下,您不想返回承诺,所以只需删除它,然后只返回数据:
App.Posts = Ember.Object.create({
load: function() {
var data = Ember.Object.create();
$.ajax({
url: 'https://api.github.com/users/octocat/orgs'
}).then(function() {
Ember.run(function() {
data.set('isLoaded', true);
});
}, function(xhr) {
Ember.run(function() {
// if using some ember stuff put here
});
});
return data;
}
});
这是jsbin显示这个工作http://jsbin.com/InONiLe/17/edit
我希望它有所帮助