在 Moq 中将传递的参数设置为特定值
Setting a passed parameter to a specific value in Moq
我正在对通过串行端口与硬件设备通信的 class 进行单元测试。我创建了一个接口来隔离 System.IO:
中的 SerialPort
class
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);
}
在我的 class 测试中有一个函数调用 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 到 return 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);
您可以使用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
中产生副作用更容易理解
为了跟进@nemesv 的回答,编译器不喜欢我的 Callback 方法中的泛型参数,所以我不得不使用 lambda 中的类型。
mock.Setup(m => m.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>()))
.Callback((byte[] buffer, int offset, int count) => {}).Returns(3);
我正在对通过串行端口与硬件设备通信的 class 进行单元测试。我创建了一个接口来隔离 System.IO:
中的SerialPort
class
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);
}
在我的 class 测试中有一个函数调用 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 到 return 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);
您可以使用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
为了跟进@nemesv 的回答,编译器不喜欢我的 Callback 方法中的泛型参数,所以我不得不使用 lambda 中的类型。
mock.Setup(m => m.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>()))
.Callback((byte[] buffer, int offset, int count) => {}).Returns(3);