Search code examples
vb.netunit-testingeventsmstestmicrosoft-fakes

Unit Testing RaiseEvent in Vb.net using MSTest+MSFakes only


Conceptually, I am a little bit lost on Events themselves, so any information here would be helpful.

Specifically, I have a very simple Property Setter which raises an event, and I want to confirm

  1. that this event is raised and also
  2. that the proper parameters have been passes to said event. (although 2. may be unnecessary for this particular event.)

I am trying to contain the overhead in my Unit Testing project, that is, avoid any additional coding in the project being tested.

The code is as follows.

Public Class myItem

Shared Event ItemOpened As EventHandler(Of EventArgs)

.........

Public Property Open() As Boolean
     Get
        Return mOpen
     End Get
     Set(ByVal value As Boolean)
        mOpen = value
        RaiseEvent ItemOpened(Me, New EventArgs)
     End Set
  End Property

All code is being done in VB.net, which is primary reason why I have not found a good enough resource online for this yet. And also, I am not using a third-party mocking framework such as Nunit or RhinoMock, only MS built in Unit Testing frameworks in VS2012.

Also, similarly, I would like to test FirePropertyChangedNotification() on certain setter methods such as follows....

Public Property myBool() As Boolean
 Set(ByVal Value As Boolean)
        FirePropertyChangedNotification("myBool")
        mViewOnly = Value
 End Set
End Property

In which FirstPropertyChangedNotification() is as follows.....

Protected Sub FirePropertyChangedNotification(ByVal propName As String)

  If Not Initializing Then
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName))
     RaiseEvent EntityChanged(Me, New PropertyChangedEventArgs(propName))
  End If
End Sub

Solution

  • I'm not sure why you want to use Fakes here... You can just use a delegate in you test to subscribe to your event. Now change the property from the test and set a boolean or even place the assert in the delegate.

    This is what I'd do in C#, autoconverted to VB.NET (which in my case is very rusty...) This works on my machine. Any improvements from a VB.NET expert are welcome:

    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    Imports System.ComponentModel
    
    Namespace UnitTestProject2
        Public Class Sut
            Implements INotifyPropertyChanged
    
            Public Property StringProperty() As String
                Get
                    Return String.Empty
                End Get
                Set(value As String)
                    OnPropertyChanged("StringProperty")
                End Set
            End Property
    
            Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    
            Protected Sub OnPropertyChanged(ByVal name As String)
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
            End Sub
        End Class
    
        <TestClass> _
        Public Class UnitTest1
            <TestMethod> _
            Public Sub TestMethod1()
                Dim sut As New Sut()
                Dim triggered = False
    
                AddHandler sut.PropertyChanged, Sub(o, e)
                                                    Assert.AreEqual("StringProperty", e.PropertyName)
                                                    triggered = True
                                                End Sub
                sut.StringProperty = "test"
    
                Assert.IsTrue(triggered)
            End Sub
    
            <TestMethod> _
            Public Sub TestMethod2()
                Dim sut As New Sut()
                Dim triggered = False
    
                AddHandler sut.PropertyChanged, Sub(o, e)
                                                    Assert.AreSame(sut, o)
                                                    triggered = True
                                                End Sub
    
                sut.StringProperty = "test"
    
                Assert.IsTrue(triggered)
            End Sub
        End Class
    End Namespace