2011-08-19 63 views
1

我需要單元測試響應SerialDataReceived事件System.IO.Ports.SerialPort的事件處理程序。此事件處理程序的簽名如何創建一個具有私有構造函數的單元測試類型的實例?

void SerialDataReceived(object sender, SerialDataReceivedEventArgs e) 

所以,當我的單元測試調用到方法,它需要一個SerialDataReceivedEventArgs實例。但是這個對象有一個私有構造函數。那麼我怎樣才能得到一個SerialDataReceivedEventArgs進入該方法?

我敢肯定,我必須在這裏錯過一個明顯的技術,我有一個漫長的一天...任何建議嗎?

+0

你可以使用模擬框架來模擬事件嗎? – luketorjussen

+1

你可能想看看這個 - http://stackoverflow.com/questions/7045776/strategy-to-simulate-events-in-object-under-test – luketorjussen

回答

4

可以使用反射創建所需類型的實例:

var args = typeof(SerialDataReceivedEventArgs) 
    .GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new [] { typeof(SerialData) }, null) 
    .Invoke(new object[] { SerialData.Chars }); 
+0

謝謝亞歷山大。我知道添加MSpec標籤會有好處;-)花了很多時間調查Moles後,我想出了一個稍微不同的解決方案,請參閱下面的答案。 –

2

您不能直接創建具有私有構造函數的類的實例。你可以使用反射來做到這一點,但這是一個非常討厭的解決方案。

1

我最終重構我的代碼,以消除私有的構造函數,像這樣:

private void HandleSerialDataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     SerialDataReceived(sender, e.EventType); 
    } 

    /// <summary> 
    /// This method executes in response to the <see cref="ISerialPort.DataReceived"/> event 
    /// via <see cref="HandleSerialDataReceived"/> and is called on its own worker thread. 
    /// </summary> 
    internal void SerialDataReceived(object sender, SerialData eventType) 
    { 
    ... 
    } 

所以現在我能做的我單元測試SerialDataReceived,並直接傳遞SerialData參數。

但是,我認爲我更喜歡Alexander的解決方案,因爲它不需要我重新生成我的生產代碼。

相關問題