Как издеваться над SerialDataReceivedEventArgs - PullRequest
6 голосов
/ 28 сентября 2011

У меня есть драйвер периферийного устройства, который использует последовательный порт для связи с периферийным устройством.Я хочу провести модульное тестирование этого драйвера и попытался смоделировать последовательный порт.Поэтому я создал оболочку для фреймворка типа SerialPort, чтобы он реализовывал интерфейс:

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

    event SerialDataReceivedEventHandler DataReceived;

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

Теперь я создал макет, используя moq:

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

Затем я хочу поднять DataReceived событие.Но SerialDataReceivedEventArgs не позволяет мне установить свойство EventType.Поэтому я попытался также смоделировать SerialDataReceivedEventArgs, получив в итоге

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

Но вторая строка вызывает NotSupportedException: недопустимая установка для не виртуального (переопределяемого в VB) члена: a => a.EventType

Как я могу поднять событие?Или как я могу издеваться над аргументами события?

Ответы [ 2 ]

10 голосов
/ 28 сентября 2011

SerialDataReceivedEventArgs не обязательно должен быть посмеянным. Его можно создать с помощью отражения:

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

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

Затем событие может быть вызвано на макете экземпляра, используя «реальный» экземпляр аргумента вентиля:

scannerPort.Raise( s => s.DataReceived += null, eventArgs );
3 голосов
/ 28 сентября 2011

Я думаю, что я мог частично решить вашу проблему, ответив, как вызвать событие, следующим образом:

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

Насмешка SerialDataReceivedEventArgs немного сложнее, так как у него нет конструктора по умолчанию.Я постараюсь обойти в ближайшее время.

РЕДАКТИРОВАНИЕ: Спасибо @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 );
        }
...