Установка переданного параметра на определенное значение в Moq

Я тестирую модуль для класса, который общается с аппаратным устройством через последовательный порт. Я создал интерфейс для изоляции класса SerialPort в 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);
}

В моем тестируемом классе есть функция, которая вызывает Read и проверяет наличие определенных значений. Например:

  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 является экземпляром ISerialPort.

Я пытаюсь написать несколько тестов для функции IsDevicePresent, используя Moq для имитации ISerialPort. Однако я не могу понять, как заставить Moq устанавливать значения в переданном массиве байтов (buffer). Я могу заставить Moq вернуть 3, но как я могу заставить Moq установить первый байт в buffer на 0x07?

var mock = new Mock<ISerialPort>();
mock.Setup(m => m.Read(It.IsAny<byte[]>(), It.IsAny<int>(),It.IsAny<int>()))
        .Returns(3);

person CurtisHx    schedule 06.06.2015    source источник


Ответы (2)


Вы можете использовать метод Callback для доступа к входящим параметрам и установки первого элемента переданного в буфере:

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; });

Вы можете сделать то же самое внутри 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;
    });

Но использовать Callback легче, чем создавать побочный эффект внутри Returns

person nemesv    schedule 06.06.2015

Чтобы продолжить ответ @nemesv, компилятору не понравились общие параметры в методе обратного вызова для меня, поэтому мне пришлось использовать типы в лямбда-выражении.

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