2010-09-25 226 views
1

在我看來,有些代碼比其他代碼更容易進行單元測試。我喜歡爲高度功能的代碼編寫單元測試(通過這個,我指的是主要對它們的參數進行操作並返回計算結果的函數)。你如何測試非功能代碼?

但是,當代碼更多地關注它的副作用時,測試它變得更加困難。例如,我在工作中使用的套接字類具有這樣聲明的方法:

void Socket::Create(void); 

它不接受任何參數,並且不返回任何結果。在出錯時拋出,但底層調用的直接結果(socket())被類本身隱藏。

任何人都可以推薦技術或可能是一本書,或網站學習單元測試代碼,主要是關於其副作用的更高級的技術?

+2

它寫入功能! – muhmuhten 2010-09-25 03:28:26

回答

2

這將是我的意見,你不應該在乎它做什麼,只是它的工作原理。因此,您不需要測試該方法,只需確保您嘗試執行的基礎操作成功即可。如果確實如此,那麼一切都很好,如果沒有,那麼你需要修正一些問題。這可以被測試。

雖然我的意見可能與「TDD」不符合,所以要把它看作是值得的。

+1

這個。你不需要測試'socket.Open',套接字類的作者會這樣做。您將測試*使用該套接字*進行操作。套接字現在是打開的,將它傳遞給你的函數,它將套接字作爲參數之一,並測試它做了你認爲應該做的事情。這可能會開始落入*整合*測試 - 但它仍然是測試跑步者的目標。 – 2012-05-04 02:40:13

4

我會拋出這個,但我不認爲它會幫助你的具體例子。有一個通用的概念叫做依賴注入或控制反轉,它允許你將基礎設施依賴從你的業務邏輯中解脫出來。假設您有一個名爲SubmitLoanApplication的例程,它執行驗證,執行業務邏輯並最終將數據提交給數據庫。對此進行單元測試很困難 - 但通過IoC,您可以針對接口編寫業務邏輯代碼,並傳入業務邏輯最終操作的接口實例。在您的生產代碼中 - 該實例連接到數據庫。在您的單元測試代碼中 - 該實例是靜態的,您的調用返回可預測的結果。

+0

有趣。這正是我正在尋找的東西。 – dicroce 2010-09-25 03:39:36

+0

@dicroce:儘管如此。如果你這樣做,你究竟在測試什麼?您正在測試方法調用。你沒有測試實時實現。正如所述,恕我直言,這種無用的。 – 2010-09-25 03:44:59

+0

+1。 @Noon:您仍然需要集成或功能測試套接字/數據庫/任何內容,但IoC可以讓您快速隔離地測試其他類,並且只需極少的設置裝置。 – TrueWill 2010-09-25 03:52:11

1

我不確定是否要測試調用此方法的代碼的方法Socket :: Create(void)或 。 在第一種情況下,您想要爲現有功能編寫測試。 所以,你可能想讀...

http://www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf

或更好的書......

http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052

在你需要一個測試替身第二種情況(我們曾經允許稱他們爲嘲笑......)。請參閱...

http://xunitpatterns.com/

這兩本書與你提到的那種處理問題準確。 總之,解決方案是以這樣一種方式劃分問題,即大多數功能很容易測試,而且只有儘可能少的功能是不可測試的。

0

當你公開這個,看起來你需要在這裏進行一些灰盒測試。

您會將此方法視爲單元測試中的黑盒子。

  • 您爲呼叫成功的環境中設置此方法
  • 你看事情怎麼樣了。
  • 您可以調用此方法。
  • 你檢查事情是否以你期望的方式改變。

  • 您的呼叫失敗的環境中設置此方法

  • 調用此方法
  • 你檢查它拋出預期的異常