2011-09-25 79 views
3

我是新來的單元測試& TDD和閱讀一些文章,我決定在我的小項目開始後TDD。這是一個簡單的劇院票預訂,它也使用NHibernate & Repository模式。我決定先爲我的數據模型寫一些測試,所以我開始對實體進行簡單的CRUD操作。我面臨的第一個問題是具有多對一關係的實體。例如我有有許多-to-one關聯到主任實體(每個展會都有一個董事)一顯示實體,因此對於測試Show.Create方法我不得不創建一個主任實體來分配他首先顯示。單元測試的數據模型:相關實體

由於單元測試極力勸阻編寫相關的測試,我怎麼能繞過這個問題未做任何依賴這些相關實體?

回答

3

我覺得將TDD當作一個如何使用某些東西的例子很有幫助,爲什麼這個行爲很有趣。

因此,例如,在你的應用程序,你可能有這樣的行爲:

它的創建當A顯示與導演有關。

然而,這不是很有趣。爲什麼這很有價值?它在哪裏使用?如果您可以展示某些重要的行爲方面,那更有意思。

一個節目的聲譽開始了與它的導演的聲譽。

然後,您可以編寫此行爲的例子:

Given a director with a reputation of 75% 
When he creates a new show 
Then the show should start with a reputation of 75%. 

這將是更有趣的行爲。我們實際上可以創建一個具有這種聲譽的節目,而不使用Hibernate。我有時候會把這樣的例子作爲測試中的評論。 (我用這個作爲例子,因爲我不知道爲什麼用導演創建節目對你來說很重要!)

對於像NHibernate這樣的東西,要麼使用覆蓋整個應用程序的全棧場景,要麼集成測試只需通過與其導演構建一個節目來檢查映射,或者手動檢查應用程序的工作情況。如果你正確地使用NHibernate,你可以假設NHibernate將繼續工作,所以與你將要改變的代碼相比,你需要更少的測試。

我的經驗是,它是確定以創建真正的域對象(顯示,導演等),而不是嘲笑他們。但是,如果您有任何複雜的計算 - 例如,計算一次Show一旦開始幾個晚上的聲望可能會很複雜 - 那麼您可以注入一個模擬來幫助解決這個問題,並且您的行爲也會相應改變:

A show uses the reputation rules for its reputation 

// Given the reputation rules 
(mock out the reputation) 

// When a show is created with a director 
(create the show) 

// And it's shown for 3 nights with varying reviews 
(associate the reviews with the show) 

// Then it should use the rules to calculate its reputation 
(verify that when you get the reputation, the show asks the mock for help). 

希望這可以讓你知道它在哪裏可能是有用的嘲笑,以及它可能不需要。這越練習越自然。

+0

謝謝你的有用答案。 完全測試實體的目的是檢查映射文件的健康性等,但在閱讀您的解釋之後,我認爲它應該在集成測試中進行分類,並且不能進行單元測試。我對嗎 ? – sos00

+0

絕對 - 做一個集成測試。映射文件的行爲只有在與真實數據庫一起使用時纔有價值。 – Lunivore

0

只需創建一個IDirector接口,您將放入顯示實體的構造函數中。這樣,您可以在分配給節目之前創建導演的模型(測試)實現。只需使用一些虛擬數據或我們的Rhino Mocks自己實現IDirector接口。一個例子見http://haacked.com/archive/2006/06/23/usingrhinomockstounittesteventsoninterfaces.aspx

+0

謝謝,我熟悉存根和模擬對象,但在這種情況下,我想測試一個真正的插入測試數據庫,所以爲了添加新的顯示到顯示錶我需要一個真正的導演記錄在那裏。我不知道也許我錯了,對真正的數據庫進行測試並不是單元測試的重點? – sos00

+0

單元測試的挑戰是正確隔離被測單元。因此,在測試Show時,您不必關心Director。我不確定如何使用NHibernate生成的實體來實現該功能,但可以想象,您可以創建一個僅用於滿足Show的構造函數的Director模型實體。 – kroonwijk