2014-10-31 77 views
1

我想用MSTest編寫單元測試,驗證某個事件在控件元素被更改後被調用。不幸的是,對於comboBoxComPort(它是一個WinForms控件)事件處理程序「comboBoxComPort_SelectedIndexChanged」下面的代碼永遠不會被調用。這當然會導致測試代碼中的匿名處理程序不被調用。如何對基於UI的事件進行單元測試?

[TestMethod()] 
public void ComboBoxComPort_SelectionChanged_DirtyEventFired() 
{ 
    ConfigUI target = new ConfigUI(); 
    var accessibleTarget = new PrivateObject(target); 
    ComboBox comboBoxComPort = (ComboBox)accessibleTarget.GetField("comboBoxComPort"); 

    bool dirtyEventCalled = false; 
    target.DirtyEvent += delegate 
    { 
     dirtyEventCalled = true; 
    }; 

    comboBoxComPort.SelectedIndex = comboBoxComPort.Items.Count - 1; 

    Assert.IsTrue(dirtyEventCalled); 
} 

爲了簡單起見,我們假設這是在「的SelectedIndexChanged」 -handler:

public class ConfigUI 
{ 
    [...] 

    private void comboBoxComPort_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     DirtyEvent(); 
    } 
} 

任何人能告訴我,爲什麼測試失敗?我知道,在單元測試中訪問私有成員通常不是一個好主意,但我沒有看到測試UI行爲的更好方法。對此的建議當然也是受歡迎的。

回答

0

這是您的註冊處理程序嗎?

target.DirtyEvent += delegate 
{ 
    dirtyEventCalled = true; 
}; 

如果事件確實提高,但這並不意味着,當是不允許的事件「泡沫或隧道」 ......根據不同的情境,事件可以被認爲是在處理時的處理程序將被調用第一個處理程序接收控件。 WPF對這個概念特別挑剔,迫使處理程序將ISHandled位設置爲false,以便事件在其他位置浮動。

如果可以的話;在事件的第一個處理程序中設置斷點,然後在該事件的測試中設置斷點。重新啓動應用程序,並確保第一個處理程序首先看到它。在退出之前查看該處理程序中的事件數據。在第一個處理程序退出時,如果你的測試處理程序沒有被調用,那是因爲事件被認爲是「滿意的」。這應該讓你更接近找到解決方案。

+0

感謝您的回覆,我不完全確定我得到你的意思是「第一處理程序」。我試着調試代碼,基本問題是「comboBoxComPort_SelectedIndexChanged」沒有被調用(通過在那裏設置一個斷點來驗證),這在我的眼中應該發生在線 comboBoxComPort.SelectedIndex = comboBoxComPort.Items.Count - 1之後; 另外我正在使用WinForms。 – flix 2014-10-31 14:03:35

+0

查看事件的第一個處理程序將是首先註冊的處理程序,在應用程序代碼(而不是測試代碼)中設置斷點(如果可以的話),然後遵循接下來會發生的事情。 – 2014-10-31 14:59:33

0

我會介紹一個ConfigUI類的接口(因爲你想看到一個控件調用該類上的方法,對吧?),然後使用Moq庫在測試中模擬ConfigUI並使用Moq.Verify看到該方法被調用(你可以要求驗證說多少次,等等......)

相關問題