ember集成测试错误。处理异步副作用

时间:2013-09-06 18:43:59

标签: javascript testing ember.js integration-testing ember-testing

我正在尝试使用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被解析。我希望立即过渡到路线,以便我可以显示加载微调器。

1 个答案:

答案 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

我希望它有所帮助