1

我正在尝试 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()(转换也会触发相同的错误)。我也不想为了使测试工作而更改应用程序代码。

我还能做些什么来修复错误吗?

注意:我故意不在模型挂钩中返回承诺,否则 UI 将被阻塞,直到承诺解决。我希望立即转换到路线,以便我可以显示加载微调器。

4

1 回答 1

3

Ember.run当您使用某些触发异步代码的方法时,例如 ajax、setInterval、 indexeddb api 等。您需要将这些方法的已解析回调委托给同步。因此,为此更改代码是处理此问题的正确方法:

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

我希望它有帮助

于 2013-09-06T19:14:27.327 回答