I need to unit test an event handler that responds to the SerialDataReceived event of System.IO.Ports.SerialPort. This event handler has the signature

void SerialDataReceived(object sender, SerialDataReceivedEventArgs e)

So when my unit test calls into the method, it needs a SerialDataReceivedEventArgs instance. But that object has a private constructor. So how do I get a SerialDataReceivedEventArgs to pass into the method?

I'm sure I must be missing an obvious technique here, I have had a long day... Any advice please?

有帮助吗?

解决方案

You can create an instance of the desired type using reflection:

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

其他提示

You can't create instances of classes with private constructors directly. You could use reflection to do it, but that is a pretty nasty solution.

I eventually refactored my code to eliminate the private constructor, like this:

    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)
    {
     ...
    }

So now I can do my unit testing on SerialDataReceived and pass it the SerialData parameter directly.

However, I think I prefer Alexander's solution because it doesn't require me to re-factor my production code.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top