2017-03-16 56 views
0

我有一個類可以加載圖像,關閉它或重命名它(至少現在,將來會有更多的操作與打開的文件)。測試有狀態類

我用Facade模式實現了它(我認爲是這樣)。

當我試圖爲它編寫測試時,我很快注意到我需要用不同的前提條件測試它(例如,在調用某種方法之前加載圖像時)。而且,當我添加新的操作時,測試的數量非常巨大,而且會迅速增長。據我所知,這些不是單元測試,而是端到端測試。

我是TDD的新手,有誰能告訴我有這樣複雜的測試是否正常嗎?

我期待我的班太多責任的答案,還是讓我們想想辦法:

// pseudo-code 

// #1 - my way 
function onRenameButtonClick(newName) { 
    imageFacade.rename(newName) 
} 

// #2 - the other way 
function onRenameButtonClick(newName) { 
    if (imageController.isOpened()) { 
    imageRenamer.rename(imageController.image, newName) 
    } 
} 

最終我還是需要測試正確的行爲#2,它仍然會涉及使用不同的前提條件。

你如何處理這種情況?這是正常的還是我做錯了什麼?

P. S.這裏是我的門面類的骨架,請注意,在config中有純函數,它們實際工作,並且actions正在拼接這些純函數並根據狀態觸發事件。

function makeImageWTF(loader, renamer) { 
    return { 
    state: { 
     image: null, 
     filePath: null, 
     isLoading: false 
    }, 
    config: { 
     loader, 
     renamer 
    }, 
    triggers: { 
     opening: new Bus(), 
     opened: new Bus(), 
     closed: new Bus(), 
     renamed: new Bus(), 
     error: new Bus() 
    }, 
    actions: { 
     open: function(path) {}, 
     close: function() {}, 
     rename: function(newName) {} 
    } 
    } 
} 

這裏是測試

骨架
describe('ImageWTF', function() { 
    describe('initial state', function() { 
    it('should be that', function() { 
     var wtf = makeImageWTF() 
     assert.deepEqual({ 
     image: null, 
     filePath: null, 
     isLoading: false, 
     }, wtf.state) 
    }) 
    }) 

    describe('#open(path)', function() { 
    it('sets isLoading') 
    it('calls config.loader with path') 
    it('sets image, fileName') 
    it('triggers loading, loaded or error') 
    it('clears isLoading') 
    }) 

    describe('#close()', function() { 
    describe('when image is opened', function() { 
     it('resets image') 
     it('triggers closed') 
    }) 

    describe('when image is NOT opened', function() { 
     it('triggers error') 
    })  
    }) 

    describe('#rename()', function() { 
    describe('when image is opened', function() { 
     it('calls config.renamer with oldName and newName') 
     it('sets fileName') 
     it('triggers renamed') 
    }) 

    describe('when image is NOT opened', function() { 
     it('triggers error') 
    }) 
    }) 
}) 

回答

0

(單位)測試就像是生產代碼 - 他們可以變得很複雜。但是,目標當然應該儘可能簡單。

如果你還沒有測試你的代碼,我建議你開始寫測試來覆蓋最重要的用例。一旦你有適當的工作,你可以重構它們。但對我來說,主要關注的是如何進行測試,您將會學到很多東西。

如果他們從一開始就不是「單元測試」,我就不會太在意,只需將其更改爲適合您的應用程序。

儘量不要將測試與生產代碼結合起來,因爲您希望能夠靈活地重構生產代碼而不必同時更改測試(當然還有其他方法)。對我來說單元測試實際上就是讓它更容易,更快地改變和重構代碼。他們不會捕捉到應用程序中的所有錯誤或行爲 - 因爲您還需要關注其他類型的測試。