Создание события с NSubstitute в VB.NET - PullRequest
0 голосов
/ 06 октября 2018

У меня проблемы с вызовом события в модульном тесте с использованием VB.NET и NSubstitute.Пересматриваемый интерфейс определяет событие:

Event BlockOfVehiclesProcessed(source As Object, stats As ProcessingStats)

Тестируемый класс регистрирует обработчик для события.В модульном тесте я хочу вызвать событие, чтобы вызывался обработчик в тестируемом классе.Основываясь на документации NSubstitute (все, к сожалению, на C #) и различных ответах на Stackoverflow и т. Д., Я попробовал различные варианты этого:

AddHandler mock.BlockOfVehiclesProcessed, Raise.EventWith(New ProcessingStats(50))

Но я не нашел ничего, что компилируется.Одно сообщение об ошибке:

Value of type 'EventHandlerWrapper(...)' cannot be converted to '...BlockOfVehiclesProcessedEventHandler'

Я попытался передать 0 аргументов и 2 аргумента в EventWith (), я попытался явно указать тип аргумента для EventWith (), и я попытался Raise.Event (), но я могуне найти волшебную последовательность, чтобы сделать компилятор счастливым.У кого-нибудь есть пример работающего модульного теста VB, который вызывает событие?

1 Ответ

0 голосов
/ 07 октября 2018

Тогда проблема в том, что NSubstitute не поддерживает анонимные типы обработчиков событий, созданные vb.net, когда событие объявляется без явно предоставленного типа обработчика событий.

Если использование NSubstitute является обязательным (и как ответ на вопрос) объявление события явно предоставленного типа обработчика событий решит вашу проблему.

' Example with Action as event handler type
Public Interface IVehicleProcessor
    Event BlockOfVehiclesProcessed As Action(Of Object, String) 
End Interface

Public Class System
    Private ReadOnly _processor As IVehicleProcessor
    Public Property ProcessedStats As String

    Public Sub New(IVehicleProcessor processor)
        _processor = processor
        AddHandler _processor.BlockOfVehiclesProcessed, Sub(sender, stats) ProcessedStats = stats
    End Sub
End System

' Test
Public Sub ShouldNotifyProcessedStats()
    Dim fakeProcessor = Substitute.For(Of IVehicleProcessor)
    Dim system As New System(fakeProcessor)

    ' Raise an event with known event handler type
    AddHandler fakeProcessor.BlockOfVehiclesProcessed, 
        Raise.Event(Of Action(Of Object, String))(fakeProcessor, "test-stats")

    system.ProcessedStats.Should().Be("test-stats") ' Pass
End Sub

Другой подход заключается в создании собственной поддельной реализации интерфейса с событием.Я нашел этот подход намного лучше, только потому, что вам не нужно менять свой производственный код, потому что некоторая среда тестирования не поддерживает языковые функции vb.net.

Public Class FakeVehicleProcessor
    Implements IVehicleProcessor

    Public Event BlockOfVehiclesProcessed(source As Object, stats As String) Implements IVehicleProcessor.BlockOfVehiclesProcessed

    ' Use this method to raise an event with required arguments
    Public Sub RaiseEventWith(stats As String)
        RaiseEvent BlockOfVehiclesProcessed(Me, stats)
    End Sub
End Class

' Test
Public Sub ShouldNotifyProcessedStats()
    Dim fakeProcessor As New FakeVehicleProcessor()
    Dim system As New System(fakeProcessor)

    fakeProcessor.RaiseEventWith("test-stats")

    system.ProcessedStats.Should().Be("test-stats") ' Pass
End Sub
...