2013-10-23 74 views
0

我有以下方法:如何爲更改數據的方法編寫單元測試?

Void UpdateUser(User user){} 

我需要檢查這個方法是否能正常工作。

我已經使用一個單獨的數據庫來檢查這在單元測試。但是很多有經驗的人說如果我用這種方法不是單元測試的話;這就是集成測試。

但我不知道如何模擬單元測試。

UpdateUser方法中編寫的代碼將嘗試使用實體框架更新數據。

如果我嘲笑(其實我也不怎麼這樣做),這將如何與實體框架一起工作?

+1

使用實體框架模擬數據庫有數百個博客和數千個問題。你嘗試了什麼,你發現了什麼,沒有發現什麼? – CodeCaster

+1

您想要了解的基礎問題是如何實現依賴注入。我建議在那裏開始你的研究。 [爲什麼使用依賴注入?](http://stackoverflow.com/q/14301389/580951) – Romoku

+0

請發佈您的自定義數據上下文類 - 一個包含'DbSet '屬性,以便我可以發佈答案與您的設置相符。 –

回答

2

模擬意味着你開發你的軟件組件(類)的方式是任何具有行爲的類都被使用/消費/作爲接口(或抽象類)調用。你編程抽象。運行時您使用某些東西(服務定位器,DI容器,工廠等)來檢索/創建這些實例。

最常用的方法是用施工注塑Here是一個很好的解釋,爲什麼會使用DI,以及如何做到這一點的例子。

在你的情況下,你使用實體框架的組件(你的倉庫的實例)必須實現一個倉庫界面,任何使用倉庫的類都應該使用它作爲界面。

這樣,你可以模擬你的unittests中的存儲庫。這意味着你創建了一個unit-test-repository類(與任何數據庫或EF無關),並且在你創建你想要單元測試的類的實例時使用它。

希望這會有所幫助。有很多來源可以找到。我個人只讀this book,我發現它非常好。 This是作者的博客。

-1

使用事務,並在測試

+0

是的,這就是我在做什麼?但無論如何,人們說嘲笑。我也覺得這是編程的好方法 –

+3

-1這根本不是*單元測試*的方式。 –

+0

@KeithPayne,如何做單元測試?如何模擬? –

0

可以使用事務和回滾或創建測試用戶嘗試的更新結束時回滾事務。斷言,然後在finally塊中刪除測試用戶。

你可以使用像moq,rhino等模擬框架。moq很容易,你可以找到許多用DI像統一框架來演示moq的例子。

+3

-1回滾數據庫正在測試,但它不是*單元測試*。 –

+0

@KeithPayne,請發表你對我所問的答案。我必須做單元測試,而不是集成測試。請發表您的寶貴答案 –

+0

@DavidArno由於您無法在單元測試的上下文中鎖定數據庫以防止另一個進程修改底層數據,因此無法確定。如果其他類似的與數據庫相關的測試同時運行,並且所有這些測試都沒有通過所有其他可能的測試知識來防止意外數據編碼,則它將失敗。 –

0

如果你的類是這樣

public class UserRepository() 
{ 
    Sqlcontext _context; 
    void UpdateUser(User user) 
    { 
     _context.Users.Add(user); 
    } 
} 

那麼這是不是單元測試。

雖然這不是一個單元測試,如果你堅持連接數據庫並對其進行測試,則可以將功能改成

User UpdateUser(User user) 
{ 
    _context.Users.Add(user); 
    return user; 
} 

和測試,如果

user.Id > 0 

在這裏,你是基本上只是測試實體框架。

0

「我用一個單獨的數據庫單元測試,以檢查它。但是許多 有經驗的人說,如果我用這個方法不會是單元測試 ;。這是集成測試」

這些人是錯誤的,儘管他們假設的經驗。出於某種原因,單元測試都是關於單獨測試代碼部分的錯誤概念近年來越來越流行。實際上,單元測試都是關於編寫作爲一個單元的測試,換句話說,它們是孤立存在的,一個單元測試的結果不會影響另一個測試。

如果您的UpdateUser方法直接訪問EF,那麼只要您確保數據庫保證在每次測試結束時回滾到其開始狀態,那麼您將進行單元測試。但是,爲每個測試設置數據庫並確保其可靠地回滾可能需要很多工作。這就是爲什麼經常使用嘲笑。其他答案已經涵蓋了mcoking EF,所以我不會重複一遍。

爲了極大地簡化您的測試,您可以在UpdateUser和EF之間插入一層外推層。換句話說,UpdateUser類提供了一個接口實例,該實例是其進入EF的網關。它不直接與EF交談。然後模擬EF,你只需提供一個模擬的接口實現。然後,這就將測試對象EF的需求推向了更基本的層次,並帶有更多基本的類似於CRUD的行爲。

+0

由於您比其他人所看到的經驗更加尊重,所以問題不在於隔離,而在於數據庫的性質。如果OP在每個線程上使用單獨的數據庫實例,那麼通過數據庫進行測試可以是單元測試。即使是從單獨組件反彈的測試,也可以進行單元測試,只要測試是快速,自動化,隔離和確定性的。測試數據庫時,確定性是殺手級的。沒有任何方法可以消除來自其他進程/線程的意外數據的可能性。 –

+0

@KeithPayne,該死的,我發現自己不得不同意你的看法。 :) 當考慮到並行運行測試時,數據庫測試確實不能進行單元測試。真正的單元測試必須支持並行運行。 –

相關問題