2010-05-13 57 views
5

給定一個基本庫界面:ASP.NET MVC - 如何單元測試存儲庫模式中的邊界?

public interface IPersonRepository 
{ 
    void AddPerson(Person person); 
    List<Person> GetAllPeople(); 
} 

有了一個基本的實現:

public class PersonRepository: IPersonRepository 
{ 
    public void AddPerson(Person person) 
    { 
     ObjectContext.AddObject(person); 
    } 

    public List<Person> GetAllPeople() 
    { 
     return ObjectSet.AsQueryable().ToList(); 
    } 
} 

這怎麼能以一種有意義的方式,你的單元測試?由於它跨越邊界並從數據庫中進行物理更新和讀取,這不是單元測試,而是集成測試。

還是想要單元測試這首先是錯誤的?我應該只在存儲庫上進行集成測試嗎?

我一直在google搜索主題和博客經常說做一個實現IRepository存根:

public class PersonRepositoryTestStub: IPersonRepository 
{ 
    private List<Person> people = new List<Person>(); 
    public void AddPerson(Person person) 
    { 
     people.Add(person); 
    } 

    public List<Person> GetAllPeople() 
    { 
     return people; 
    } 
} 

但是,這並不單元測試PersonRepository,它測試PersonRepositoryTestStub(不是非常有幫助)的實施。

回答

6

在這個特定情況下,我認爲你不需要爲你的存儲庫類進行單元測試,因爲實現只是調用ObjectContext對象,所以它就像測試你沒有構建的東西(這是不是這個想法)。如果您沒有任何複雜的邏輯,我建議不要浪費時間爲該課程進行單元測試。你對PersonRepositoryTestStub的描述是用於測試DAL之上的圖層庫的假實現。

+0

是的,那就是我所傾向的。我的下一個問題是關於下一層(在這種情況下是IService)。如果存儲庫不值得測試,並且PersonService.GetAllPeople()簡單地說「return _repository.GetAllPeople();」,那麼測試中是否有任何要點? – 2010-05-13 01:28:44

+0

@JK測試它沒有任何好處。如果一個類/方法只是在其他類之間提供粘合,我通常不會單獨測試它。我只是將所有東西連接在一起,並運行幾種方法的煙霧/集成測試。例如。我可以創建一個新對象,保存並檢索它嗎? – Ryan 2010-05-13 01:39:47

+0

你可以測試你的倉庫被調用。我同意這不是一個有意義的測試,我會專注於測試那些對您的業務更批評的方法。 – uvita 2010-05-13 01:45:11

1

當我認爲這種類型的測試有意義時,您的存儲庫接口是通用的。例如。

public interface IEntity 
{ 
    int Id { get; set; } 
} 

public interface IRepository<TEntity> 
    where TEntity : IEntity 
{ 
    void Add(TEntity entity); 
    List<TEntity> GetAll(); 
} 

如果您有接口的多個實現,那麼它也可以寫一個通用的測試夾具,測試針對的接口,使您能以一個單一的測試夾具測試多個倉庫的實現。這種方法不區分單元測試和集成測試,因爲它不知道實現是什麼。

讓我知道這種事情是否感興趣,我可以發佈一個完整的例子。

+0

我希望看到一個完整的例子。 – 2012-11-30 09:02:15

0

我會直接測試依賴於DAL實現的業務邏輯層(對DAL確切實現有強烈的參考)或間接(通過接口從DAL抽象)。

我不是很喜歡測試,它使用存根實現,只是將數據庫調用包裝成未完成的事務(即使拋出異常時測試結束時還原所有數據更改)。

+0

我認爲這是一種糟糕的做法,因爲單元測試應該很快運行,因爲您將有許多單元測試需要在測試套件中運行。訪問數據庫會降低速度,因此CI構建將花費更長的時間,並會阻止許多小的提交 – skyfoot 2011-11-17 16:43:29

2

我遇到了同樣的問題。我寫了一堆單元測試,針對我的存儲庫接口的實現,它是一個假存儲庫。完成之後不久,我意識到我編寫了單元測試來測試僞造的存儲庫,並且我只是爲了支持單元測試而編寫了僞造的存儲庫。這看起來像是大量無用的代碼。

我得出的結論是,我不需要單元測試,但假的存儲庫實現是好的,因爲我可以使用它作爲我的服務(因此我的控制器)的存儲庫使用,以便針對這些單元測試將是可預測的(感謝預定義的假存儲庫)。

因此,我已經決定在單元測試中對虛假的存儲庫進行測試,因爲它們有助於測試我的虛假存儲庫,這樣我可以確信,我的應用程序的更高級別使用完全測試的虛假。

換句話說,僞存儲庫和針對僞存儲庫的單元測試是針對更高級別應用程序的「支持強制轉換」,以及針對更高級別應用程序的單元測試。

希望有所幫助。