Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock SerialDataReceivedEventArgs

I have a peripheral driver that uses the serial port to communicate with the peripheral device. I want to unit test this driver and tried to mock the serial port. Therefore I created a wrapper for the framework type SerialPort to have it implement an interface:

public interface IScannerPort
{
    Handshake Handshake { get; set; }
    bool IsOpen { get; }

    event SerialDataReceivedEventHandler DataReceived;

    void Close( );
    void Open( );
    string ReadLine( );
}

Now I created a mock using moq:

Mock<IScannerPort> scannerPort = new Mock<IScannerPort>( );

I then want to raise the DataReceived event. But SerialDataReceivedEventArgs doesn't let me set the EventType property. So I tried to mock SerialDataReceivedEventArgs as well, ending up with

Mock<SerialDataReceivedEventArgs> args = new Mock<SerialDataReceivedEventArgs>();
args.SetupProperty(a => a.EventType, SerialData.Eof);

But the second line raises a NotSupportedException: Invalid setup on a non-virtual (overridable in VB) member: a => a.EventType

How can I raise the event? Or how can I mock the event args?

like image 828
PVitt Avatar asked Sep 28 '11 10:09

PVitt


1 Answers

The SerialDataReceivedEventArgs doesn't necessarily be mocked. One can create an instance of it using reflection:

ConstructorInfo constructor = typeof (SerialDataReceivedEventArgs).GetConstructor(
    BindingFlags.NonPublic | BindingFlags.Instance,
    null,
    new[] {typeof (SerialData)},
    null);

SerialDataReceivedEventArgs eventArgs = 
    (SerialDataReceivedEventArgs)constructor.Invoke(new object[] {SerialData.Eof});

Then the event can be raised on the mocked instance using the "real" instance of the vent args:

scannerPort.Raise( s => s.DataReceived += null, eventArgs );
like image 109
PVitt Avatar answered Oct 19 '22 23:10

PVitt