2011-12-19 109 views
8

我試圖找到從我的邏輯中解耦messageboxes的最佳方法,所以我可以正確地對它進行單元測試。現在我想知道如果我只是創建了一個單獨的幫助類(C#),我可以稍後爲我的消息框存根就足夠了。例如:Messagebox和單元測試

static class messageBoxHelper 
{ 
    public static void msgBoxAlg(string message, string title, MessageBoxButtons buttons, MessageBoxIcon icons, bool show) 
    { 
     if (show) 
     { 
      MessageBox.Show(message, title, buttons, icons); 
     } 
} 

然後每次我需要使用一個消息我只是用messageboxHelper/msgBoxAlg(...),而不是messagebox.show(...)。使用布爾秀,我可以在測試過程中啓用或禁用它。

我只是想知道這是否是「正確的方式」。我的意思是,有沒有更好的或更好的方法來正確地做到這一點?我不能丟棄信息盒,他們會向用戶傳遞「重要」信息(「您想關閉這個窗口嗎?」YES/NO等)。也可能是因爲我沒有使用正確的軟件工程,我應該更多地將我的消息箱與我的bussinesslogic分離開來?

回答

29

是的,這是正確的方式。而是靜態類,你應該實現IDialogService並注入到應該顯示的對話框類:

public interface IDialogService 
{ 
    void ShowMessageBox(...); 

    ... 
} 

public class SomeClass 
{ 
    private IDialogService dialogService; 

    public SomeClass(IDialogService dialogService) 
    { 
     this.dialogService = dialogService; 
    } 

    public void SomeLogic() 
    { 
     ... 
     if (ok) 
     { 
      this.dialogService.ShowMessageBox("SUCCESS", ...); 
     } 
     else 
     { 
      this.dialogService.ShowMessageBox("SHIT HAPPENS...", ...); 
     } 
    } 
} 

在測試期間,SomeClass你應該注入IDialogService的模仿對象,而不是真實的。

如果您需要測試更多UI邏輯,請考慮使用MVVM模式。

+0

謝謝,非常明確的解釋! – 2011-12-19 13:35:57

+0

我喜歡「IDialogService」這個術語作爲抽象! – Samuel 2016-09-09 17:18:49

2

研究控制反轉(IoC),基本原理是執行操作的東西應該作爲接口傳遞,然後使用IoC容器將接口綁定到應用程序的特定實現。爲了輕鬆實現這個,你的情況傳遞確實消息框爲一個接口,在單元測試中創造該消息框服務的模擬(假的)版本,它不會顯示一個消息框

看看http://martinfowler.com/articles/injection.html的事有關IoC的詳細信息,我最喜歡的容器是Ninject(http://ninject.org)

1

理想情況下,您希望使用單元測試進行測試的代碼是邏輯而不是UI。因此,你的測試邏輯不應該真的顯示一個消息框。如果您想要測試UI,那麼我會建議Coded UI Tests

根據你的問題判斷,我想你的代碼不應該真的用MessageBox。也許應該考慮使用回調或任意Action或Luke McGregor和Sergey V提到的方法。

1

「單元測試」的確切含義是對原子行爲的測試。這不是您可以爲您的代碼進行的唯一一種代碼驅動的測試。特別是對於你提到的「是/否」對話框來測試更長的場景,大規模的代碼驅動測試通常比單元測試更有效。

但是要能寫他們更容易,這將是很好的不僅是要創造一個特殊的服務,因爲它是由謝爾蓋·提到,但也使其調用異步:

public interface IDialogService 
{ 
    Task<bool> ShowYesNoMessageBox(...); 
    ... 
} 

通過包裝提示消息框非異步服務調用並嘲笑它們,對於更長的場景,您將開始通過在實際發生之前預測用戶操作(執行「Arrange」而不是「Act」)來開始違反「Arrange-Act-Assert」模式,這會導致大量測試中出現問題,特別是如果您的測試使用BDD/SpecFlow完成。使這些調用異步可以避免這種問題。使用消息框查看我的blog article以獲取更大規模測試的詳細信息和示例。