正在测试的代码
Public Class ObservableName
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Sub RaisePropertyChanged(propertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
Private _Name as String
Public Property Name As String
Get
Return _Name
End Get
Set(value As String)
_Name = value
Me.RaisePropertyChanged(NameOf(Me.Name))
End Set
End Property
End Class
Public Class ViewModel
Public ReadOnly Property MyName As ObservableName
Public Property CountOfChanges As Integer
Public Sub New(name As ObservableName)
Me.MyName = name
AddHandler Me.MyName.PropertyChanged, AddressOf Me.MyName_PropertyChanged
End Sub
Protected Sub MyName_PropertyChanged(sender as Object, e As PropertyChangedEventArgs)
If e.PropertyName.Equals(NameOf(Me.MyName.Name)) = True Then
Me.CountOfChanges += 1
End If
End Sub
End Class
使用NUnit
和NSubstitute
进行测试
测试更改Name(引发PropertyChanged事件)将更新CountOfChanges proerty
<Test>
Public Sub CountOfChanges_NameChanged_ShouldIncreaseByOne()
Dim previuosCount As Integer = 0
Dim nextCount As Integer = previuos + 1
Dim fakename As ObservableName = Substitute.For(Of ObservableName)()
Dim vm As New ViewModel(fakename)
vm.CountOfChanges = previuosCount
AddHandler vm.MyName.PropertyChanged, Raise.Event(Of PropertyChangedEventHandler)(vm.MyName, New PropertyChangedEventArgs(NameOf(vm.MyName.Name)))
Assert.AreEqual(nextCount, vm.CountOfChanges)
End Sub
使用上面的代码永远不会引发PropertyChanged
事件,但是直接使用传递INotifyPropertyChanged
的下一个测试会成功提升事件
<Test>
Public Sub PropertyChanged_RaiseEvent()
Dim test As INotifyPropertyChanged = Substitute.For(Of INotifyPropertyChanged)()
Dim isRaised As Boolean = False
AddHandler test.PropertyChanged, Sub() isRaised = True
AddHandler test.PropertyChanged, Raise.Event(Of PropertyChangedEventHandler)(test, New PropertyChangedEventArgs("test"))
Assert.IsTrue(isRaised)
End Sub
答案 0 :(得分:2)
你真的需要在这里使用NSubstitute并使用白盒测试吗? 如果您设置纯粹的技术兴趣&#34;除此之外,在测试中设置vm.myName.Name属性会更简单,然后声明vm.CountOfChanges增加了。这将是一个黑盒子&#34;方法,它不依赖于内部实现的细节,因此更加健壮。 它仍然完全测试您的功能,只是省略了实现细节
要了解为什么它不能按预期工作,请考虑以下内容。 NSubstitute使用Castle.DynamicProxy来实现替换 - 使用的机制是继承。 事件是通过使用具有相同签名的私有委托字段实现的语言功能。事件的整个目的是封装委托。 由于委托字段是私有的,因此无法在派生类中访问它,因此无法触发事件。 要在继承的类中引发基类事件,基类必须有一个用于引发事件的vitual方法,继承的类必须覆盖该事件,例如,请参阅this link,但对此有很多很好的解释。幅。