在 VB.NET 中使用 NSubstitute 发起一个事件
Raising an event with NSubstitute in VB.NET
我在使用 VB.NET 和 NSubstitute 的单元测试中引发事件时遇到问题。被模拟的接口定义了一个事件:
Event BlockOfVehiclesProcessed(source As Object, stats As ProcessingStats)
正在测试的 class 为事件注册了一个处理程序。在单元测试中,我想引发事件,以便调用被测 class 中的处理程序。基于 NSubstitute 文档(不幸的是,所有 C#)和 Whosebug 等的各种答案,我尝试了各种排列:
AddHandler mock.BlockOfVehiclesProcessed, Raise.EventWith(New ProcessingStats(50))
但我还没有找到任何可以编译的东西。一条错误消息:
Value of type 'EventHandlerWrapper(...)' cannot be converted to '...BlockOfVehiclesProcessedEventHandler'
我尝试将 0 个参数和 2 个参数传递给 EventWith(),我尝试为 EventWith() 明确指定类型参数,我尝试了 Raise.Event(),但我找不到神奇的序列让编译器开心。有没有人有引发事件的有效 VB 单元测试示例?
然后问题是 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
我在使用 VB.NET 和 NSubstitute 的单元测试中引发事件时遇到问题。被模拟的接口定义了一个事件:
Event BlockOfVehiclesProcessed(source As Object, stats As ProcessingStats)
正在测试的 class 为事件注册了一个处理程序。在单元测试中,我想引发事件,以便调用被测 class 中的处理程序。基于 NSubstitute 文档(不幸的是,所有 C#)和 Whosebug 等的各种答案,我尝试了各种排列:
AddHandler mock.BlockOfVehiclesProcessed, Raise.EventWith(New ProcessingStats(50))
但我还没有找到任何可以编译的东西。一条错误消息:
Value of type 'EventHandlerWrapper(...)' cannot be converted to '...BlockOfVehiclesProcessedEventHandler'
我尝试将 0 个参数和 2 个参数传递给 EventWith(),我尝试为 EventWith() 明确指定类型参数,我尝试了 Raise.Event(),但我找不到神奇的序列让编译器开心。有没有人有引发事件的有效 VB 单元测试示例?
然后问题是 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