Jasmine:Backbone.history.loadUrl打破了不相关的测试

时间:2013-09-23 16:13:16

标签: backbone.js jasmine

我发现导航到不同URL以进行查看和路由器行为测试的唯一方法是使用Backbone.history.loadUrl()。 Backbone.history.navigate('#something',true)和router.navigate('#something,{trigger:true,replace:true}及其任何组合在测试中不起作用。我的应用程序不使用pushstate。< / p>

这在单个测试的上下文中正常工作。

describe('that can navigate to something as expected', function(){
  beforeEach(function() {
    this.server = sinon.fakeServer.create();
    //helper method does my responds to fetches, etc. My router in my app is what starts Backbone.history
    this.router = initializeBackboneRouter(this.server, this.fixtures, false);
  }); 
  afterEach(function(){
    this.server.restore();
    Backbone.history.stop();
    Backbone.history.loadUrl('#');
  });

  it('should create the view object', function(){
    Backbone.history.loadUrl('#something');
    expect(this.router.myView).toBeDefined();
  });
});

在测试期间,您可以看到主干正在按照URL的预期附加哈希:localhost:8888 / #some取决于测试。

不幸的是,loadUrl似乎在测试行为的方式上引入了很多不一致。在我的一个涉及一些异步JS的测试中,我需要等待一个AJAX调用才能完成,大约50%的时间会因超时失败,或者有时会定义未定义的未定义。如果我控制了我希望存在的数据,那么我知道它不是BS测试。

it('should add the rendered html to the body', function(){
  runs(function(){
    Backbone.history.loadUrl('#something');
  });
  waitsFor(function(){
    var testEl = $('#title');
    if(testEl.length > 0){ return true; }
  }, 1000, 'UI to be set up');
  runs(function(){
    var testEl = $('#title');
    expect(testEl.text()).toEqual(this.router.model.get(0).title);
  });

});

这里的重要注意事项是它只在所有测试运行时失败;它自己运行它100%的时间。

我的问题是:Backbone.history.loadUrl是一个在茉莉花的骨干应用程序周围进行程序导航的坏方法吗?我觉得我已经尝试了一切来模拟用户访问特定URL。我的拆机不正确吗?我试过没有Backbone.history.loadUrl('#');并且有不同的行为但没有通过测试。

核心问题似乎是在几个,几百个甚至几个茉莉花测试的背景下,Backbone.history并没有清除它自己并且作为自身的一个实例而不是完全重新初始化每次测试。

1 个答案:

答案 0 :(得分:0)

这很糟糕。 解决方案是编辑我的代码以添加一个加载完成标志,当我确定DOM是100%完成加载时,该标志设置为true。

然后我编写了一个辅助函数,等待每个测试的根目录中的beforeEach函数中的该标志为真。

var waitForLoadingComplete = function(view){
  waitsFor(function(){
    if(view.loadingComplete == true){return true;}
  }, 100, 'UI Setup Finished');
}

之后我将我的设置重构为辅助函数:

var setupViewTestEnvironment = function(options) {
  var temp = {};
  temp.server = sinon.fakeServer.create();
  temp.router = initializeBackboneRouter(temp.server, options.fixture);
  waitForLoadingComplete(temp.router.initialview);
  runs(function(){
    Backbone.history.loadUrl(options.url);
    temp.view = temp.router[options.view];
    temp.model = temp.router[options.model];    
    waitForLoadingComplete(temp.view);
  });
  return temp;
}

使用示例:

  beforeEach(function() {
    this.testEnv = setupViewTestEnvironment({
      url: '#profile', 
      view: 'profileIndex', 
      model: 'myModel', 
      fixture: this.fixtures
    });  
  }); 

之后我有一个视图,我已经加载了,我可以放心已完成加载,所以我可以测试DOM上的东西或我想做的任何其他事情。