2013-09-23 73 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上的東西或其他我想做的事情。