2013-09-23 72 views
0

我发现导航到不同URL来执行视图和路由器行为测试的唯一方法是使用Backbone.history.loadUrl()。在测试中,Backbone.history.navigate('#something',true)和router.navigate('#something,{trigger:true,replace:true}及其任意组合在我的应用程序中不能使用pushstate。茉莉花:Backbone.history.loadUrl打破无关测试

这正常工作检验单的范围内

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:本地主机:8888 /#的东西根据测试

不幸的是,loadUrl似乎在测试的行为方式上引入了很多不一致的地方。在我的一个测试中,涉及到一些异步JS,我需要等待AJAX​​调用才能完成,大约50%的时间会因为超时而失败,或者有时需要定义为undefined才能定义。如果我调出我希望在那里的数据,所以我知道这不是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并没有自行清理,而是作为自己的一个实例而不是完全重新初始化在每次测试中。

回答

0

这吸了。 解决方案是编辑我的代码有点添加一个加载完成标志设置为true,当我确定DOM是100%完成加载。

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

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上的东西或其他我想做的事情。