灰烬整合测试错误.处理异步副作用 [英] ember integration test error. dealing with asynchronous side-effects

查看:90
本文介绍了灰烬整合测试错误.处理异步副作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试ember的集成测试程序包( http://emberjs.com/guides/testing/集成/),但出现此错误

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,我们可以通过打开浏览器的控制台来查看.

我相信导致此错误的原因是App.Postsload()方法中的行data.set('isLoaded', true);. (链接至代码: http://jsbin.com/InONiLe/9/edit )

现在,如果将data.set('isLoaded', true);行包裹在Ember.run()中,则它将按预期工作,并且测试将通过.

但是,我在很多模型中都使用了这种模式,我不想只用Ember.run()包装每个.set()(转换也会触发相同的错误).我也不想为了使测试工作而更改应用程序代码.

还有其他方法可以解决该错误吗?

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

解决方案

使用某些方法时,将触发异步代码,例如ajax,setInterval,indexeddb api等.您将需要将这些方法的解析后的回调委托给Ember.run,因此ember将这些操作在您的运行循环中排队,并确保应用程序同步.因此,为此更改代码是处理此问题的正确方法:

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

我希望对您有帮助

I'm trying ember's integration testing package (http://emberjs.com/guides/testing/integration/) but I am getting this error

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

I've made a JSBin to reproduce this error: http://jsbin.com/InONiLe/9, which we can see by opening up the browser's console.

I believe what's causing this error is the line data.set('isLoaded', true); in the load() method of App.Posts. (Link to code: http://jsbin.com/InONiLe/9/edit)

Now, if I wrap the data.set('isLoaded', true); line in an Ember.run(), then it will work as expected and the test will pass.

However, I am using this pattern for a lot of my models and I don't want to just wrap every .set() with an Ember.run() (transitions also trigger the same error). I also don't want to change application code for the sake of making the test work.

Is there something else I can do to fix the error?

Note: I am purposely not returning a promise in the model hook because otherwise the UI is blocked until the promise is resolved. I want the transition to the route to happen immediately so that I can display a loading spinner.

解决方案

When you use some methods, that triggers async code, like ajax, setInterval, the indexeddb api etc. You will need to delegate the resolved callbacks of theses methods to Ember.run, so ember will queue these operations in your runloop and it ensure that application is in sync. So changing your code for this is the correct way to handle this:

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);      
    });    
  }
});

Other advise is to always use the Ember.RSVP.Promise, because is more compatible with Ember than $.Defered. $.Deferred is returned by $.ajax.

Here is an updated jsbin http://jsbin.com/InONiLe/10/edit

UPDATE

Because in your case you don't want to return a promise, so just drop it, and just return the data itself:

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;
  }
});

Here is the jsbin showing this working http://jsbin.com/InONiLe/17/edit

I hope it helps

这篇关于灰烬整合测试错误.处理异步副作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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