2010-06-15 89 views
3

我正在學習TDD,並且對私有/受保護變量有疑問。我的問題是:如果我想測試的函數是對一個私有變量進行操作,我應該如何測試它?測試驅動開發:爲私有/受保護變量編寫測試

這裏是我的工作的例子:

我有一個稱爲Table類,它包含稱爲internalRepresentation的實例變量是2D陣列。我想創建一個名爲multiplyValuesByN的函數,它將二維數組中的所有值乘以參數n

所以我寫它的測試(在Python):

def test_multiplyValuesByN (self): 
    t = Table(3, 3) # 3x3 table, filled with 0's 
    t.set(0, 0, 4) # Set value at position (0,0) to 4 
    t.multiplyValuesByN(3) 

    assertEqual(t.internalRepresentation, [[12, 0, 0], [0, 0, 0], [0, 0, 0]]) 

現在,如果我做internalRepresentation私人或受保護的,這個測試將無法正常工作。我該如何編寫測試,因此它不依賴於internalRepresentation,但在調用multiplyValuesByN後仍然測試它看起來正確?

回答

10

您不應該依賴於對象的內部表示。這就是爲什麼它被標記爲私有或受保護的原因。考慮當您調用t.multiplyValuesByN(3)時可觀察到的變化。然後,測試你可以觀察到什麼。

def test_multiplyValuesByN (self): 
    t = Table(3, 3) # 3x3 table, filled with 0's 
    t.set(0, 0, 4) # Set value at position (0,0) to 4 
    t.multiplyValuesByN(3) 

    assertEqual(t.get(0,0), 12) 
0

不要測試私有變量/狀態。您的測試應確認被測單元符合其規格,並且該規格取決於其界面。所以你的測試應該根據你的測試單元的輸入來寫,並且驗證輸出是否符合你的期望。

您希望能夠更改被測單元的實現(例如,效率原因),並確認其按預期工作。因此,檢查私人狀態會在這種情況下造成困難。

3

如果是內部的,那麼在課堂之外它就是nobodys業務,包括測試。

在TDD中,您正在設計您的類的API,未來的客戶端也只能看到該類的可觀察行爲。

我知道這說起來容易做起來難。

在測試你經常看到一個模式reoccuring:設置 - 經營 - 檢查( - 拆解)

設置階段負責把對象的先決條件狀態。

檢查階段應通過該類的可觀察行爲驗證後置條件。如果它永遠不會出現,那麼存儲隱形狀態是沒有意義的。

+0

...也被稱爲Arrange-Act-Assert(但沒有用於拆解的一致性匹配 - 猜測這是一件好事,它沒有多少用處!) – 2010-06-16 14:31:35

+0

是的,這就是爲什麼我把它放在括號內。這是有時需要的那些實際的東西之一,但不適合理論。我喜歡3-A的一致性。之前沒有聽說過,謝謝! – 2010-06-16 16:38:11

3

其他人已經發布了很好的答案,但恕我直言,未能強調一件事:設計方面(儘管彼得Tillemans提到它)。所以我對此加了一點解釋。

在進行TDD時,您正在有效地測試API的設計以及實施。如果您發現方法調用的結果很難或不可能從外部看到,這幾乎總是表明您的類接口設計得不好。如果爲你的班級編寫測試很困難,在現實生活中通常也很難使用它 - 你的單元測試實際上是班上的第一批客戶。因此,如果您發現測試用例在使用類接口時遇到困難,則應考慮返回並重新設計API以使其更易於使用(如果可能,不要妥協封裝)。