2012-08-08 90 views
1

因爲我沒有得到我的頭單元測試。放棄我的思維單元測試

我有一個服務

public interface IMyService 
{ 
    public List<Person> GetRandomPeople(); 
} 

然後在我的MVC項目我有這個服務的實現

​​3210

然後在我的控制器

public HomeController : Controller 
{ 
    IMyService _myService; 
    public HomeController(IMyService myService) 
    { 
     _myService = myService 
    } 
} 

然後在行動方法我會用

public ActionResult CreateRandom() 
{ 
    List<Person> people = _myService.GetRandomPeople(); 
    return View(people) 
} 

注:人員回購在我的服務中,只是很快輸入了這個,所以我有回購。

我的問題:我將如何測試我的服務實施在我的測試項目。我現在真的陷入了困境,我認爲這是TDD未來的「光照」時刻。

在此先感謝。

+0

我不明白你的問題。 'MyService'是一個普通的類,所以就像那樣測試它。 – 2012-08-08 12:21:33

+1

我不同意;我會考慮這個話題。這是開發新手單元測試,存儲庫模式和依賴注入的常見問題。請記住,這是[愛的夏天](http://blog.stackoverflow.com/2012/07/kicking-off-the-summer-of-love/)。 :) – TrueWill 2012-08-08 13:18:39

+0

請你能在這裏發佈你的MyService代碼爲什麼你不能測試? – 2012-08-08 16:09:32

回答

2

將服務接口注入控制器的目的是讓您單獨測試控制器。爲了測試這個,你傳入一個模擬或僞造的IMyService。

根據您的服務如何實施,您可能需要測試您的服務集成測試。這些應該與你的單元測試分開(因爲你不想連續運行它們)。

例如,假設IMyService是使用Entity Framework實現的。你需要實際運行LINQ to Entities來對數據庫進行測試。你可以使用本地數據庫,你可以用EF創建並快速填充數據庫等。這些不是單元測試(它們使用I/O),但它們仍然很重要。

其他持久性框架可能允許您針對內存數據集進行測試。沒關係;我仍然認爲這是一個集成測試(你的代碼+框架),並將它從單元測試中分離出來。

訣竅是保持業務邏輯不受服務實現的影響。儘可能限制純數據訪問代碼。你想用單元測試來測試你的業務邏輯。

編輯:

爲了解決這個問題的意見(「當你需要創建存根」):

創建存根,假貨,測試雙打,或嘲笑(有很多的術語)當你有一個你想要隔離測試的類(被測系統或SUT)並且該類已經注入了依賴關係。

這些依賴將會以某種方式抽象 - 接口,抽象類,類與虛擬方法,委託等

你的生產代碼將傳遞(類襲擊的數據庫,例如具體實現)。您的測試代碼將通過測試實現。您可以傳遞一個簡單的存根實現(只需在您的測試項目中編寫一個虛擬類來實現接口併爲其成員返回固定值),或者您可以擁有一個更好的實現來檢測調用的是什麼以及調用什麼參數被傳遞(一個模擬對象)。您可以手動編寫所有這些內容。它變得乏味,許多測試人員使用模擬對象框架(也稱爲隔離框架)。有很多(對於任何給定的語言,通常有幾個);我傾向於在.NET中使用NSubstituteMoq

學習編寫測試需要時間。它幫助我閱讀了關於這個主題的幾本書。博客帖子可能無法提供足夠的背景。 (關閉)question here有一些很好的建議。

簡短的回答是,當您的測試需要時,您可以創建存根或嘲笑。

+0

P.S.我會返回IEnumerable 而不是List。列表是一個實現細節。 – TrueWill 2012-08-08 13:20:24

+0

使用EF,可以使用Mocking Context Generator來簡化單元測試:http://blogofrab.blogspot.com/2010/08/maintenance-free-mocking-for-unit.html – 2012-08-08 21:46:40

+0

@JakubKaleta - 有趣的鏈接。我認爲[對LINQ to Entities的限制](http://msdn.microsoft.com/zh-cn/library/bb738550)需要驗證的集成測試。 – TrueWill 2012-08-08 23:45:10