2012-08-04 56 views
3

是否可以測試任何訪問winform控件的方法?以下方法訪問我窗體上的一系列控件中的Enabled屬性。不幸的是,我不知道如何進行單元測試/如果它甚至可能。訪問控件的單元測試方法

我真的很欣賞一些指針。

public void AccessToCsvFileVerificationInputs(bool access) 
    { 
     btnSelectCSVFilePath.Enabled = access; 
     nudNumberOfColumns.Enabled = access; 
     cbCurrencyPair.Enabled = access; 

     foreach (Control input in tlpColumnDataTypes.Controls) 
     { 
      input.Enabled = access; 
     } 

     foreach (Control input in tlpColumnNames.Controls) 
     { 
      input.Enabled = access; 
     } 

     nudInitialRow.Enabled = access; 
     nudFinalRow.Enabled = access; 

     btnSelectErrorLogFilePath.Enabled = access; 
    } 

回答

5

我發現最好的辦法,以這個被轉移你的應用程序設計成某種形式的模型 - 視圖 - 的*模式,其中爲的WinForms Model-View-Presenter 通常是一個不錯的選擇。

這種方式你有一個主持人/控制器類負責所有的邏輯,你有視圖持有的UI代碼。在Winforms中,您通常可以實現這一點,讓您的表單類實現一個IView接口,該接口定義它可以執行的所有操作。

然後,您提供的形式(通過它在聲明爲接口)演示 - 與構造函數依賴注入是通過它的典型方式


所以,在你的榜樣,你移動你的AccessToCsvFileVerificationInputs方法插入到演示者類中,並向演示者傳遞實現正確界面的表單實例,並說明該表單可以執行的所有操作。

事情是這樣的:

public class CsvFilePresenter 
{ 
    private ICsvFileView view_; 
    public CsvFilePresenter(ICsvFileView view) 
    { 
     view_ = view; 
    } 

    public void AccessToCsvFileVerificationInputs(bool access) 
    { 
     // Code omitted for brevity 
    } 
} 

現在這種方法隨處可見,你引用像控制UI功能直接與你,而不是引用接口:

public void AccessToCsvFileVerificationInputs(bool access) 
{ 
    view_.EnableSelectCSVFilePath = access; 
    view_.EnableNumberOfColumns = access; 
    view_.EnableCurrencyPair = access; 

    // And so on... 
} 

我故意留控制集合了 - 怎麼樣你處理這些將取決於具體情況。

因此,例如,你有這樣的ICsvFileView接口:

public interface ICsvFileView 
{ 
    bool EnableSelectCSVFilePath { get; set; } 
    bool EnableNumberOfColumns { get; set; } 
    bool EnableCurrencyPair { get; set; }   
} 

這個ICsvFileView的具體實施可能是這樣的:

public partial class Form3 : Form, ICsvFileView 
{ 
    public Form3() 
    { 
     InitializeComponent(); 
    } 

    bool ICsvFileView.EnableSelectCSVFilePath 
    { 
     get 
     { 
      return btnSelectCsvFilePath.Enabled; 
     } 
     set 
     { 
      btnSelectCsvFilePath.Enabled = value; 
     } 
    } 

    bool ICsvFileView.EnableNumberOfColumns 
    { 
     get 
     { 
      return nudNumberOfColumns.Enabled; 
     } 
     set 
     { 
      nudNumberOfColumns.Enabled = value; 
     } 
    } 

    bool ICsvFileView.EnableCurrencyPair 
    { 
     get 
     { 
      return cbCurrencyPair.Enabled; 
     } 
     set 
     { 
      cbCurrencyPair.Enabled = value; 
     } 
    } 
} 

現在你已經做到了這一點,你可以測試您的邏輯行爲(如演示者所表達的)及其與View的交互,方法是傳遞一個模擬的界面實例並設置該模擬的期望值。


請注意,如果這一切似乎有點複雜難懂那是因爲它是! Winforms的設計並非真正考慮到這種情況 - 其他框架(如WPF)也是如此,並且使這一切變得更加容易。如果你可以改變,我建議考慮它。


Martin Fowler的網頁上我掛已經退休這種模式,它移動到兩個不同的模式 - 我會繼續的術語,雖然,因爲它是衆所周知的。他的新Passive View接近我一直看MVP。

+0

嗨大衛,感謝羚牛的時間來回答我的問題。我已經通過你的回答讀了幾次n我想我現在明白了。我要去一試,看看我是怎麼回事。我在此同時將此標記爲答案n + 1。感謝你的寶貴時間! – 2012-08-04 17:52:57

+0

@HansRudel完全沒問題。如果試過後,如果沒有任何意義,只留下評論,我會盡力澄清。還有幾個人們構建Winforms MVP框架的示例項目 - 谷歌Winforms和MVP(或MVC),你應該找到一些。 – 2012-08-04 17:54:46

+0

早上,我仍然有一些問題了解這是如何工作的。我對MainForm部分類如何實現一個接口(IMainView)有基本的瞭解,該接口指定了MainForm需要實現的所有事件(按鈕點擊等)和屬性等。 MainForm實例然後通過DI傳遞給MainPresenter。我不明白,但是我怎樣才能訪問MainPresenter類中的控件屬性?我只聲明IMainForm接口中的方法,所以我如何訪問控件屬性? (對不起,如果這是一個愚蠢的問題)。 – 2012-08-06 08:33:18