2014-01-20 39 views
3

我想通過使用茉莉花測試一些視圖代碼。當視圖對象處於不同包容狀態時,我需要測試某些元素的存在,而不必在每個狀態下重複很多代碼。DRYing茉莉花嵌套描述塊

我已經得到了類NodeView,它代表了一些端點的節點,以便允許用戶使用某些行將此節點連接到其他節點。每個節點都放置在一個列(組)中,以便如果將此節點放入第一個組中,則不會顯示左端點。如果節點進入最後一個組,它將不會顯示正確的端點。我可以用茉莉花中的嵌套描述塊來管理這種情況:

var node, subject, model; 

describe("render", function() { 
    beforeEach(function() { 
    model = mockModel(); 
    }); 

    describe("when the node is into first group", function() { 
    beforeEach(function() { 
     model.isInFirstGroup.andReturn(true); 
     model.isInLastGroup.andReturn(false); 

     node = new NodeView(model); 
    }); 

    it("has the left endpoint hidden", function() { 
     expect(node.el.find('.endpoint .left')).toBeHidden(); 
    }); 

    it("has the right endpoint visible", function() { 
     expect(node.el.find('.endpoint .left')).toBeVisible(); 
    }); 
    }); 

    describe("when the node is into last group", function() { 
    beforeEach(function() { 
     model.isInFirstGroup.andReturn(false); 
     model.isInLastGroup.andReturn(true); 

     node = new NodeView(model); 
    }); 

    it("has the left endpoint visible", function() { 
     expect(node.el.find('.endpoint .left')).toBeVisible(); 
    }); 

    it("has the right endpoint hidden", function() { 
     expect(node.el.find('.endpoint .left')).toBeHidden(); 
    }); 
    }); 

到目前爲止一切正常。當我們有其他不同的狀態時,麻煩就開始了,在這種情況下,這個狀態是允許輸入的。這是一個布爾值,表示用戶是否可以畫線。如果這個布爾值爲true,那麼節點必須包含一個'輸入'類和其他東西。下面是代碼(再次渲染功能):

describe("when the node is in input state", function() { 
    beforeEach(function() { 
    model.input = true; 
    node = new NodeView(model); 
    }); 

    it("has the class input", function(){ 
    expect(node.el).toHaveClass('input'); 
    }); 
}); 

describe("when the node is not in input state", function() { 
    beforeEach(function() { 
    model.input = false; 
    node = new NodeView(model); 
    }); 

    it("has not the class input", function(){ 
    expect(node.el).not.toHaveClass('input'); 
    }); 
}); 

好了,好了,林建設一個節點時,測試生成的HTML標記(不調用渲染方法明確),但它確實在內部這項工作。當構建對象時(構造函數調用render),將調用Render,這就是爲什麼Im不在代碼中明確調用node.render()。

測試這些不同的狀態將需要測試,包括所有可能的情況:

  • 第一組 - 輸入
  • 最後一組 - 輸入
  • 第一組 - 沒有輸入
  • 最後一組 - 無輸入

如果我添加另一個布爾狀態,那麼我有8個場景,依此類推。我試圖通過使用共享的例子http://pivotallabs.com/drying-up-jasmine-specs-with-shared-behavior/清理一點點

sharedExamplesForGroupState = function() { 
    describe("(shared)", function() { 
    describe("when the node is into first group", function() { 
     beforeEach(function() { 
     model.isInFirstGroup.andReturn(true); 
     model.isInLastGroup.andReturn(false); 

     node = new NodeView(model); 
     }); 

     it("has the left endpoint hidden", function() { 
     expect(node.el.find('.endpoint .left')).toBeHidden(); 
     }); 

     it("has the right endpoint visible", function() { 
     expect(node.el.find('.endpoint .left')).toBeVisible(); 
     }); 
    }); 

    describe("when the node is into last group", function() { 
     beforeEach(function() { 
     model.isInFirstGroup.andReturn(false); 
     model.isInLastGroup.andReturn(true); 

     node = new NodeView(model); 
     }); 

     it("has the left endpoint visible", function() { 
     expect(node.el.find('.endpoint .left')).toBeVisible(); 
     }); 

     it("has the right endpoint hidden", function() { 
     expect(node.el.find('.endpoint .left')).toBeHidden(); 
     }); 
    }); 
    }); 
}); 

describe("when the node is in input state", function() { 
    beforeEach(function() { 
    model.input = true; 
    node = new NodeView(model); 
    }); 

    it("has the class input", function(){ 
    expect(node.el).toHaveClass('input'); 
    }); 

    sharedExamplesForGroupState(); 
}); 

describe("when the node is not in input state", function() { 
    beforeEach(function() { 
    model.input = false; 
    node = new NodeView(model); 
    }); 

    it("has not the class input", function(){ 
    expect(node.el).not.toHaveClass('input'); 
    }); 

    sharedExamplesForGroupState(); 
}); 
上面沒有按預期的方式輸入狀態測試沒有設定輸入狀態進行工作,所以

線,我們真正測試:

  • 輸入和沒有輸入獨立的基團的
  • 而不包括輸入測試的情況下,但其中包括model.input屬性
第一和最後一組

這並不是真正測試所有4種情況。

有關如何改進這一點以避免指數重複代碼的任何想法?

非常感謝。

回答

2

我認爲您的最新describe塊上的beforeEach正在註冊的回調函數正在被sharedExamplesForGroupState()調用的beforeEach調用覆蓋。如果爲sharedExamplesForGroupState調用創建了一個新的作用域(如將其封裝到describe塊中),它應該可以工作:

describe("when the node is in input state", function() { 
    beforeEach(function() { 
    model.input = true; 
    node = new NodeView(model); 
    }); 

    it("has the class input", function(){ 
    expect(node.el).toHaveClass('input'); 
    }); 

    describe("shared examples for group state", function() { 
    sharedExamplesForGroupState(); 
    }); 
}); 
+0

這是代碼示例中的錯誤。我已經修好了。這個問題更像是如何在嘗試測試狀態時避免測試用例重複,這些狀態需要一些初始設置必須在嵌套的beforeEach塊中完成。也許我可以解決它從共享示例中刪除所有beforeEach塊,並讓最頂級的測試聲明爲每個組合進行所需的設置。 – Ungue