使用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 args和2 args传递给EventWith(),我尝试为EventWith()显式指定arg类型,并尝试了Raise.Event(),但是我找不到创建编译器的神奇顺序快乐。有没有人举起一个活动的VB单元测试的例子?
答案 0 :(得分:2)
然后的问题是,在没有显式提供事件处理程序类型的情况下声明事件时,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