如何使用私有构造函数创建类型实例以进行单元测试?

时间:2011-08-19 07:19:28

标签: unit-testing moq mspec

我需要对响应System.IO.Ports.SerialPort的SerialDataReceived事件的事件处理程序进行单元测试。此事件处理程序具有签名

void SerialDataReceived(object sender, SerialDataReceivedEventArgs e)

因此,当我的单元测试调用方法时,它需要一个SerialDataReceivedEventArgs实例。但是该对象有一个私有构造函数。那么如何让SerialDataReceivedEventArgs传递给方法?

我确信我必须在这里错过一种明显的技巧,我度过了漫长的一天......有什么建议吗?

3 个答案:

答案 0 :(得分:4)

您可以使用反射创建所需类型的实例:

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

答案 1 :(得分:2)

您不能直接使用私有构造函数创建类的实例。你可以用反射来做,但这是一个非常讨厌的解决方案。

答案 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参数传递给它。

但是,我认为我更喜欢亚历山大的解决方案,因为它不需要我重新考虑我的生产代码。