2014-02-26 95 views
8

我最近對測試非常感興趣,我現在試圖學習以儘可能最好的方式進行單元測試。我將NUnit和Rhino Mocks一起使用。我也在Stackoverflow上閱讀了很多,但還沒有找到明確的答案來解決我的問題。Stub vs Mock當單元測試

我想知道的是,如果我有像下面這樣的方法,我應該嘲笑OfficeClass依賴關係,還要測試GetAllOffices或者只使用存根作爲依賴項,並驗證方法GetAllOffices已被調用,並且確實獲得了我希望從我的設置中找到存根的辦公室嗎?

public Offices GetAllOffices() 
{ 
    try 
    { 
     var offices = officeClass.GetAllOffices(); 
     return offices; 
    } 
} 

請問這有什麼區別,如果OfficeClass只是另一個POCO或者如果讓說,在VS嘲諷碰傷SENCE web服務?

長問題簡短:什麼時候模擬和何時在單元測試中存根?

+0

我一直在讀那篇文章早些時候,但我仍然不確定何時使用這個文章,因此我認爲這將有助於在該文章中獲得一些意見t我自己的代碼。 –

+0

不知道你從帖子中錯過了什麼 - 一切都在那裏。它列出了這兩個概念之間的所有差異。 – BartoszKP

+0

我仍然覺得我對「何時模擬和什麼時候存在於單元測試」這個問題有一個回答。) 我想我已經意識到兩者之間的區別,但不是當我應該嘲笑以及何時應該在單元測試的環境中存根對象。 –

回答

11

Mock使用框架來生成依賴項的「模擬」。例如,如果officeClass是您的數據存儲庫,那麼您可以使用模擬框架(我使用MOQ)來生成模型庫。這就是爲什麼爲你的依賴使用接口使其成爲測試的理想選擇的原因,模擬框架可以很容易地爲接口進行測試模擬。

根據我的理解,您可以手動刪除依賴項並創建罐頭響應。例如,如果您有一個接口IOfficeClass,並且您創建了一個繼承它的新類,則可以將該類注入到您的服務中以允許您使用它。

Web服務應該再次包裝在一些接口(如IRepository模式)中,這將允許您輕鬆測試您的邏輯,而無需訪問Web服務。與POCO類相同。

因此,例如,你的情況你會:

public interface IOfficeRepository 
{ 
    IQueryable<Office> GetAll(); 
} 

併爲您服務

public class MyOfficeService 
{ 
    private readonly IOfficeRepository officeRepostiory; 

    public MyOfficeService(IOfficeRepository repository) 
    { 
     this.officeRepostiory = repository; 
    } 

    public Office GetOffice(int id) 
    { 
     return this.officeRepostiory.GetAll().SingleOrDefault(o => o.Id == id); 
    } 
} 

這種方式,您還可以更改您的基礎數據源,而不必修改主應用程序或業務邏輯代碼。

單元測試看起來像這樣用起訂量:

[TestClass] 
public class OfficeUnitTest 
{ 
    private MyOfficeService service; 

    [TestInitialize] 
    public void Setup() 
    { 
     var officeRepository = new Mock<IOfficeRepository>(); 

     var office = new List<Office>(); 
     office.Add(new Office{ Id = 1 }); 

     officeRepository.Setup(m => m.GetAll()).Returns(office.AsQueryable()); 

     this.service = new MyOfficeService(officeRepository.Object); 
    } 

    [TestMethod] 
    public void TestGetById() 
    { 
     Assert.IsNotNull(service.GetOffice(1)); 

     // my mock will never return a value for 2 
     Assert.IsNull(service.GetOffice(2)); 
    } 
} 

你可以閱讀更多關於嘲笑及以下存根:

http://martinfowler.com/articles/mocksArentStubs.html

http://msdn.microsoft.com/en-us/library/ff649690.aspx

+0

我認爲_martinfowler_ one是關於** Dummy **,** Fake **,** Stubs **和** Mocks **這四種含義的很好的解釋。謝謝。 –