如何模拟SerialDataReceivedEventArgs

本文关键字:SerialDataReceivedEventArgs 模拟 何模拟 | 更新日期: 2023-09-27 18:09:51

我有一个外设驱动程序,它使用串行端口与外设设备通信。我想对这个驱动程序进行单元测试,并尝试模拟串行端口。因此,我为框架类型SerialPort创建了一个包装器,让它实现一个接口:

public interface IScannerPort
{
    Handshake Handshake { get; set; }
    bool IsOpen { get; }
    event SerialDataReceivedEventHandler DataReceived;
    void Close( );
    void Open( );
    string ReadLine( );
}

现在我使用moq:

创建了一个mock
Mock<IScannerPort> scannerPort = new Mock<IScannerPort>( );

然后我想引发DataReceived事件。但是SerialDataReceivedEventArgs不让我设置EventType属性。所以我试着模拟SerialDataReceivedEventArgs以及,以

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

但是第二行抛出NotSupportedException: Invalid setup on an non-virtual(在VB中可重写)成员:a => a. eventtype

如何引发事件?或者如何模拟事件参数?

如何模拟SerialDataReceivedEventArgs

SerialDataReceivedEventArgs不一定要被模拟。您可以使用反射创建它的实例:

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

然后可以使用vent参数的"真实"实例在模拟实例上引发事件:

scannerPort.Raise( s => s.DataReceived += null, eventArgs );

我想我可能已经部分解决了你的问题,通过回答如何引发事件,如下:

  var mockedScannerPort = new Mock<IScannerPort>();
            mockedScannerPort.Setup(sp => sp.ReadLine())
                             .Returns("123")
                             .Raises(sp => sp.DataReceived += null, new object[] { this, It.IsAny<SerialDataReceivedEventArgs>() });
            bool mockEventWasInvoked = false;
            mockedScannerPort.Object.DataReceived += (sedner, e) => mockEventWasInvoked = true;
            var retVal = mockedScannerPort.Object.ReadLine();
            Assert.AreEqual( "123", retVal );
            Assert.IsTrue(mockEventWasInvoked);

Mocking SerialDataReceivedEventArgs有点棘手,因为它没有默认构造函数。我将很快尝试一个变通方法。

EDIT:感谢@PVitt为存根SerialDataEventArgs提供解决方案。把这个贴在这里只是为了完整。

[Test]
        public void Test()
        {
            var mockedScannerPort = new Mock<IScannerPort>();
            var constructor = typeof(SerialDataReceivedEventArgs).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(SerialData) }, null);
            var eventArgs = (SerialDataReceivedEventArgs)constructor.Invoke(new object[] { SerialData.Eof });
            mockedScannerPort.Setup(sp => sp.ReadLine())
                             .Returns("123")
                             .Raises(sp => sp.DataReceived += null, new object[] { this, eventArgs });
            bool mockEventWasInvoked = false;
            SerialDataReceivedEventArgs ea = null;
            mockedScannerPort.Object.DataReceived += (sedner, e) =>
                                                         {
                                                             mockEventWasInvoked = true;
                                                             ea = e;
                                                         };
            var retVal = mockedScannerPort.Object.ReadLine();
            Assert.AreEqual( "123", retVal );
            Assert.IsTrue(mockEventWasInvoked);
            Assert.IsNotNull( ea );
            Assert.AreEqual( ea.EventType, SerialData.Eof );
        }
相关文章:
  • 没有找到相关文章