Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting a passed parameter to a specific value in Moq

I'm unit testing a class that talks to a hardware device through a serial port. I created an interface to isolate the SerialPort class in System.IO:

public interface ISerialPort
{
  String PortName { get; set; }
  bool IsOpen { get; }
  void Open();
  void Close();
  int Read(byte[] buffer, int offset, int count);
  void Write(byte[] buffer, int offset, int count);
}

There's a function in my class under test that calls Read, and checks for specific values. For example:

  public bool IsDevicePresent()
  {
     byte[] buffer = new byte[3];
     int count = 0;
     try
     {         
        port.Write(new byte[] { 0x5A, 0x01 }, 0, 2);
        count = port.Read(buffer, 0, 3);
     }
     catch (TimeoutException)
     {
        return false;
     }
     return (buffer[0] == 0x07 && count == 3);
  }

port is an instance of ISerialPort.

I'm trying to write some tests for the IsDevicePresent function, using Moq to mock an ISerialPort. However, I can't figure out how to get Moq to set values in the passed byte array (buffer). I can get Moq to return 3, but how can I get Moq to set the first byte in buffer to 0x07?

var mock = new Mock<ISerialPort>();
mock.Setup(m => m.Read(It.IsAny<byte[]>(), It.IsAny<int>(),It.IsAny<int>()))
        .Returns(3);
like image 741
CurtisHx Avatar asked Mar 15 '23 19:03

CurtisHx


1 Answers

You can use the Callback method to access the incoming parameters and set first element of the passed in buffer:

mock.Setup(m => m.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>()))
    .Returns(3)
    .Callback<byte[], int, int>((buffer, offset, count) => { buffer[0] = 0x07; });

You can do the same thing inside the Returns

mock.Setup(m => m.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>()))
    .Returns<byte[], int, int>((buffer, offset, count) =>
    {
        buffer[0] = 0x07;
        return 3;
    });

But using the Callback is more easier to follow than making the side-effect inside the Returns

like image 95
nemesv Avatar answered Mar 18 '23 07:03

nemesv