chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Hi there.

I have the following routine, which iterates through all the files in a directory. The class that the routine is a part of uses a BackhroundWorker object (m_fileReaderWorker) which is instanciated during the class creation process.

I would like to test just this routine, without creating a new class:

Private Sub WorkWithFilesInDir(ByVal aDir As DirectoryInfo)

        For Each aFile As FileInfo In aDir.GetFiles()
            If Not m_fileReaderWorker.CancellationPending Then
                ... do stuff

            Else
                Exit For
            End If
        Next

    End Sub


Here is my unit test code:

Public Sub WorkWithDirectoryTest()

        Dim target As WebsiteConverter_Accessor = New WebsiteConverter_Accessor

        Dim aDir As New DirectoryInfo("D:\site")

        target.WorkWithDirectory(aDir)

    End Sub


The unit test runs perfectly fine until it hits the line:

If Not m_fileReaderWorker.CancellationPending Then 


since m_fileReaderWorker is Nothing. How can I mock this out, so that when I run the unit test, I can force CancellationPending to return False all the time?

Cheers.
Jas.
asked by MrClyfar (5.2k points)

4 Answers

0 votes
Hi there.

One way I've found to get around this, is to have a private property in the class called FileReaderWorker which encapsulates m_fileReaderWorker.

In my test I can thus use:

Public Sub WorkWithDirectoryTest()

        Dim mockWorker As System.ComponentModel.BackgroundWorker = RecorderManager.CreateMockedObject(GetType(System.ComponentModel.BackgroundWorker), Constructor.NotMocked)
        Dim mockConverter As Mock = MockManager.Mock(Of WebsiteConverter)(Constructor.NotMocked)

        ' Mock the file reader worker in the website converter.
        mockConverter.ExpectGetAlways("FileReaderWorker", mockWorker)

        ' Make sure that CancellationPending always returns False.
        Using recorder As RecordExpectations = RecorderManager.StartRecording
            recorder.ExpectAndReturn(mockWorker.CancellationPending, False)
        End Using

        Dim target As WebsiteConverter_Accessor = New WebsiteConverter_Accessor

        Dim aDir As New DirectoryInfo("D:\site")

        target.DestinationPath = "D:\tmp"

        target.WorkWithDirectory(aDir)

    End Sub


I'm happy to use this method, but if anyone does have a suggestion on how to mock private objects in a class, then that would be very handy.

Cheers.
Jas.
answered by MrClyfar (5.2k points)
0 votes
Hi,

If youre using the latest version, try using the new Field Mocking functionality.
Using it youll be able to directly mock the private object.
answered by lior (13.2k points)
0 votes
Hi there.

I'm trying out the following example, but getting stuck.

I have this class:

Public Class Class1

    Private m_test As String = String.Empty

    Public Function GetString() As String
        Return m_test
    End Function
End Class


Here's my unit test:

<TestMethod()> _
Public Sub GetStringTest()
    Dim target As Class1 = New Class1

    Dim mockClass1 As Mock = MockManager.Mock(Of Class1)(Constructor.Mocked)

    Dim strTest As String = "Yo bro"

    mockClass1.AssignField("m_test", strTest)

    Assert.AreEqual("Yo bro", target.GetString())
End Sub


When I run the test, the call target.GetString() returns an empty string. Basically, how should I be using field mocking so that I can mock private members of a class?

Cheers.
Jas.
answered by MrClyfar (5.2k points)
0 votes
DOH! :roll:

I had the unit test written incorrectly, this works fine:

<TestMethod()> _
Public Sub GetStringTest()
    Dim mockClass1 As Mock = MockManager.Mock(Of Class1)(Constructor.Mocked)

    mockClass1.AssignField("m_test", "Yo bro.")

    Dim target As Class1 = New Class1
        Assert.AreEqual("Yo bro.", target.GetString())
        
End Sub


Cheers.
Jas.
answered by MrClyfar (5.2k points)
...