How do I create a an instance of a type with a private constructor for unit testing?
-
02-01-2021 - |
题
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.