2012-12-20 53 views
1

我只是在學習如何使用帶有MSTest的Moq。我有以下方法我想測試一下,在現有的一個應用:如何使用MSTest和Moq對此進行模擬

/// <summary> 
/// Return the marker equipment Id value give a coater equipment Id value. 
/// </summary> 
/// <param name="coaterEquipmentId">The target coater</param> 
/// <returns>The marker equipment Id value</returns> 
internal static string GetMarkerEquipmentId(string coaterEquipmentId) 
{ 
    return CicApplication.CoaterInformationCache 
     .Where(row => row.CoaterEquipmentId == coaterEquipmentId) 
     .Select(row => row.MarkerEquipmentId) 
     .First(); 
} 

CicApplication對象是一個名爲CoaterInformationCache屬性,這是CoaterInformation類列表的「全球性」的對象。

我假設我將需要以某種方式模擬CicApplication.CoaterInformationCache,我可能需要傳遞此方法一個包含CoaterInformation類列表的接口,而不是通過僅包含運行時值的全局對象訪問列表?

非常感謝

+0

作爲全局或靜態不是艱難的部分;它並沒有將這個屬性作爲一個接口,並且沒有辦法設置它,這是真正的問題。 –

+0

謝謝霍恩先生。非常有見地的答案。 –

回答

2

全局/靜態是單元測試性禍根。爲了使這個測試,你是正確的,你應該消除全球CicApplication。您可以使用相同的公共API創建一個界面,即ICicApplication,並將實例傳遞到您的應用程序代碼中。

public interface ICicApplication 
{ 
    public List<CoaterInformation> CoaterInformationCache { get; } 
} 

public DefaultCicApplication : ICicApplication 
{ 
    public List<CoaterInformation> CoaterInformationCache 
    { 
     // Either use this class as an adapter for the static API, or move 
     // the logic here. 
     get { return CicApplication.CoaterInformationCache; } 
    } 
} 

由於這是一個靜態方法,你可以把它作爲一個方法的參數,否則,靜態方法轉換爲一個實例方法的對象上初始化ICicApplication場(或許通過一個實例到構造函數) 。

然後,當您設置的單元測試,你可以通過在模擬實例中設置了起訂量:

Mock<ICicApplication> appMock = new Mock<ICicApplication>(); 
appMock 
    .SetupGet(ca => ca.CoaterInformationCache) 
    .Returns(new List<CoaterInformation> { ... }); 
+0

Scott - 如果我消除CicApplication全局並使用相同的API創建接口,那麼將實現接口的是什麼? –

+0

@RandyMinder:您將需要使用當前的靜態邏輯爲接口創建一個默認實現。我已經更新了我的答案,以包含一個示例實現。 –

相關問題