2013-11-21 154 views
1

我有進行了一系列模型上工作的業務邏輯過程,其中之一是一類:嘲諷方法

public virtual void TryToRunProcess(Model model) 
{ 
    var result = RunCheckMethodOne(model) && RunCheckMethodTwo(model); 
    if (result) 
     RunMethodThree(model); 
} 

internal virtual bool RunCheckMethodOne(Model model) 
{ 
    ... 
} 

internal virtual bool RunCheckMethodTwo(Model model) 
{ 
    ... 
} 

internal virtual void RunMethodThree(Model model) 
{ 
    ... 
} 

假設模型和其相關聯的RunCheckMethodOne()和RunCheckMethodTwo()方法足夠複雜以保證它們自己的單元測試集,我想測試RunCheckMethodOne()和RunCheckMethodTwo()的適當響應是否導致RunMethodThree()的正確執行。

我想通過嘲笑業務邏輯類,並設置兩個檢查方法返回特定結果,然後驗證第三個方法執行。

我的一個單元測試是:

[TestMethod] 
public void TryToRunProcessBothCheckMethodsAreTrueShouldExecuteMethodThreeTest() 
{ 
    var model = new Model(); 

    var mock = new Mock<ModelBusinessLogic>(); 
    mock.Setup(r => r.RunCheckMethodOne(It.IsAny<Model>())).Returns(true); 
    mock.Setup(r => r.RunCheckMethodTwo(It.IsAny<Model>())).Returns(true); 
    mock.Setup(r => r.RunMethodThree(It.IsAny<Model>())).Verifiable(); 

    mock.Object.TryToRunProcess(model); 

    mock.Verify(r => r.RunMethodThree(It.IsAny<Model>()), Times.Once()); 
} 

現在,對我來說這看起來像它應該工作,但是當我運行這個單元測試的RunCheckMethodOne()和RunCheckMethodTwo()方法不被嘲笑爲我期望;它們實際上在ModelBusinessLogic類中執行,而不是返回模擬中設置的值。

在我的實現中應該做些什麼來確保我可以將所有業務邏輯方法保留在同一個類中(以免創建過度設計的解決方案),並且仍然能夠在業務邏輯中模擬方法類來鍛鍊其他方法中的特定場景?

我正在使用.Net Framework 4.5和Moq 4.0.0.0。

+1

請問mock.Callbase = true有幫助嗎? –

+0

我試過使用該標誌,這似乎沒有幫助。根據Moq的intellisense幫助,當沒有安裝程序存在時,CallBase屬性默認爲基本虛擬實現。這看起來不像它會幫助我,因爲我已經有了Setups,我希望明確地使用它,而不是ModelBusinessLogic中的底層實現。 –

回答

1

你需要做兩件事情:

  • mock.CallBase = TRUE;
  • 使內部方法公開或內部保護(顯然不太理想)。

我也認爲你應該考慮打破你的課堂,如果你說,有足夠的複雜性來保證個人測試。這聽起來不像是對我來說過度工程。

編輯

您也可以添加

你的課,如果它不是強命名。有關更多信息,請參見this question

+1

或受保護的內部。 – dcastro

+0

Thx,也補充說。 –

+1

謝謝詹姆斯!將受保護的內部關鍵字添加到RunCheckMethodOne(),RunCheckMethodTwo()和RunMethodThree()的方法簽名中似乎可以解決問題。我不需要設置mock.CallBase = true來獲得我正在尋找的行爲。我的下一個問題(純粹是爲了學術上的平靜)是爲什麼受保護的內部方法在這種情況下與內部方法有不同的表現? –