2010-11-28 52 views
7

我有這個班,我想用TDD構建,但是我失敗了。這是一個非常基本的類,名爲SubMissions,它所做的只是從SQL數據庫中提取一些數據。測試驅動開發不適合我的班級

所以它的方法,如getSubMissionForPage()getSubMissionFromId()等。

我嘗試使用TDD構建它。我的第一個測試包含對getSubMissionPage()的調用,其目的只是返回數據。因此,使這個測試失敗是非常困難的,因爲它可以返回任何數據,我不能想出一個辦法使其失敗。

我知道讓你的測試失敗是知道要實施什麼的第一步,但是如果實際上沒有失敗的測試方法,你會怎麼做?

+1

在這些情況下,您可以使用您希望返回的特定數據預加載數據庫。然後,您可以檢查它(例如,行ID或行數)以確保您獲得的數據大致正確 – obfuscation 2010-11-28 22:35:28

回答

8

無論何時您依賴外部數據源,您的測試總是會失敗。如果連接掉到你的數據庫上怎麼辦?如果表格不存在,您試圖從中獲取數據?如果返回的數據不是您期望的數據,該怎麼辦?

連接到數據庫的測試類比測試HelloWorld.java稍微複雜一點,因爲你需要某種方式到mock the DB。您可以瞭解有關Mock Objects here的更多信息。

簡而言之,您的測試/軟件可能總是失敗。如果你不認爲你的測試可能失敗,那麼你對這個問題空間的思考不夠。

+0

+1作爲簡短回答。 – 2010-11-28 22:38:33

2

好吧。有幾種標準類型的東西可以測試:null和空字符串spring。如果數據真的可以是任何東西,那麼任何事情都是有效的。

從測試數據庫開始,可能不是潛入TDD的最佳方式。從沒有依賴關係的類開始。想象一下,一盤棋,你可能有類,如:

  • 廣場
  • 位置(行,板上方的山坳)

我將與位置開始自它沒有依賴性,然後Square因爲它只依賴於Location,然後Board因爲它只依賴於Square。

3

TDD的美妙之處在於,如果您發現測試很難寫入,它就會指向設計中的潛在問題。在這種情況下,抽象您的數據訪問邏輯。例如,您可以使用依賴注入將接口發送到數據訪問存儲庫(在您的測試用例中使用假或模擬),這樣可以讓您將數據訪問測試與邏輯測試隔離開來。即構建一個處理數據訪問的SubmissionRepository,並且您的提交類處理業務邏輯,轉到您的存儲庫以進行基本的粗劣和整形操作。

當然,在某些時候,您需要測試一些數據訪問作爲集成測試的一部分,但我始終使用從TDD開始的練習來幫助驅動更多的分離設計。

+0

作爲示例,我可能會構建一個虛假的存儲庫,該存儲庫返回給定ID的假記錄或給定數組頁面等 - 這樣你就可以測試前兩個函數,並考慮你的倉庫應該如何處理無效ID等等。 – 2010-11-28 22:36:57

+0

+1依賴注入。這確實與tdd – 2010-11-29 18:55:57

+0

+1一起用於嘲笑或僞造外部資源 – JeffH 2010-12-03 21:12:50

0

你不必爲每一種方法都寫一個測試。如果你認爲一個測試太簡單了,你可以決定不寫一個測試。有些人會爭辯說,你還應該寫一個測試,但我認爲有些情況下你不需要。

看看這個JUnit的常見問題解答:http://junit.sourceforge.net/doc/faq/faq.htm#best_3

0
  1. 修改你的類拋出任何運行時異常,看到測試失敗。
  2. mofify測試期望異常,並看到測試失敗

(1)和(2)只是練習,應該可以幫助您以確保測試工作。

現在問自己問題:什麼可能是測試失敗的原因?我認爲在你的情況下,上榜理由是這樣的:1。 沒有連接到DB 2.錯了DB模式 3.數據不一致

這裏有模擬這些原因的方法:1. 關閉DB或更改您用於連接的憑證/ jdbc URL。 2.刪除感興趣的表或更改其列的名稱。 3.數據不一致有點困難。這通常發生在DB約束未正確定義的情況下。有時候人們會這樣做,使圖式更通用。如果不是你的情況,那麼就忘了#3。

與TDD祝你好運! 我相信在未來你的測試場景會變得更加複雜。

1

'getSubMissionPage'不應該只是返回任何數據 - 它應該發出一個特定的請求,然後根據請求返回somehing。

您需要配置'SubMissions'以使用模擬數據源,然後測試該類是否生成正確的請求並將數據正確映射到對象中。

3

如果您希望測試失敗,請讓方法拋出RuntimeException。 Eclipse將爲您填充具有適當UnsupportedOperationException的方法存根。

然後爲了讓測試變爲綠色,只需讓方法返回null而不是拋出。

不要打擾連接到數據庫,直到一個額外的測試或兩個逼你。

5

從數據庫檢索不是從TDD開始的地方。

你可能會在網上看到一些TDD的例子。鮑勃馬丁的bowling game scoring是一個有趣的地方開始。

話雖這麼說...

我的第一個測試包含到getSubMissionPage(),調用其唯一目的就是返回數據。因此,使這個測試失敗是非常困難的,因爲它可以返回任何數據,我不能想出一個辦法使其失敗。

其目的不是返回數據,而是返回正確的數據。

對此進行測試的方法是爲其提供一個數據庫,以使其返回特定結果並查看它的結果。當然,直到你編寫正確的代碼之後,你纔會首先寫測試,然後在看到失敗後才真正實現。

TDD涉及數據庫的難點在於,使用真實數據庫進行測試可能會很慢,並且使得測試可重複可能很困難,因爲您的測試有時會更改數據。爲了處理這些問題,您可以從DbUnit這樣的工具獲得幫助,模擬JDBC,使用內存數據庫,並使用回滾來確保您的測試不會做出永久性更改。

但你最好不要從數據庫的東西開始。