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
Hello!

I searched for a bug like this and found one reported mid 2005 for v. 2.3.

Same symptom as that report: Failure every other time (100% every other time, I have tested this thoroughly).

Context: Using only TypeMock 3.0.1, I have a fairly big test harness, moving legacy code towards better code. Have experienced some gotchas with TypeMock but have worked around most. This is giving me serious pain right now (since yesterday).

A class (called BusinessService) is mocked in a testfixture but the mock exhibits strange behavior when tests creating a concrete instance (of a subclass of it actually, it is abstract) runs before. Thats when I get the alternating pass/fail behavior.

I am grasping for straws right now, this is the setup method (I know... vb - yuck):

    
Private Sub SetupBsMock()
        SyncLock (Me)
            If _businessMock Is Nothing Or _businessService Is Nothing Then
                _businessMock = MockManager.MockObject(GetType(BusinessService))
                _businessMock.Strict = True
                _businessMock.StrictStatic = True

                Debug.Assert(Not _CName Is Nothing, "CName should be set when mock is created")
                Debug.Assert(_CName <> "", "CName should be set when mock is created")
                _businessMock.AlwaysReturn("GetCName", _CName)
                _businessMock.AlwaysReturn("GetServiceName", _serviceName)

                _businessService = CType(_businessMock.Object, BusinessService)
                Debug.Assert(_businessService.GetCName() = _CName, "Service should return name as setup")
            End If
        End SyncLock
    End Sub


Note that I have moved the assertion here from the test code, as a debug assertion. Same behavior - it fails every other time.

I have tried all kinds of silliness (extra nulling out, blabla) with no good results.

Please help me OBK...

Best regards!
asked by mawi (2k points)

7 Answers

0 votes
Hi Marcus,
Tell me what do you see when you run the TypeMock Tracer? is the method being mocked? called?
What is the type of BusinessObject (abstract/ interface)?
If you print out the type of businessService what do you get?
answered by scott (32k points)
0 votes
Hi Marcus,
Tell me what do you see when you run the TypeMock Tracer? is the method being mocked? called?

I haven't used the "TypeMock tracer". In the code I:
* Create a mockobject for BusinessService
* Configure it with two AlwaysReturn settings to return a string each
* Cast a reference to the mockobjacts object

* Call one of the AlwaysReturn methods, expecting the string I just set a couple of lines up. <-- this fails every other time

What is the type of BusinessObject (abstract/ interface)?

BusinessService is an abstract class.

If you print out the type of businessService what do you get?


Here are new asserts in the code that pass showing you typenames:

    
Private Sub SetupBsMock()
        SyncLock (Me)
            If _businessMock Is Nothing Or _businessService Is Nothing Then
                _businessMock = MockManager.MockObject(GetType(BusinessService))
                _businessMock.Strict = True
                _businessMock.StrictStatic = True

                Debug.Assert(Not _CName Is Nothing, "CName should be set when mock is created")
                Debug.Assert(_CName <> "", "CName should be set when mock is created")
                _businessMock.AlwaysReturn("GetCName", _CName)
                _businessMock.AlwaysReturn("GetServiceName", _serviceName)

                _businessMock.ExpectConstructor()
                '_businessService = New TestBs
                _businessService = CType(_businessMock.Object, BusinessService)

                Debug.Assert(_businessService.GetType.FullName = "MockBusinessService")
                Debug.Assert(_businessMock.GetType.FullName = "TypeMock.MockObject")
                ' This fails every other time:
                Debug.Assert(_businessService.GetCName() = _CName, "Service should return name as setup")
            End If
        End SyncLock
    End Sub


So I just discovered that if I do this exact same thing in the testclass (not part of the harnessclass) it starts to work. The following is a method that uses only local variables but creates a MockObject of the same class.

Although it is completely independent of any other code (referencewise) it pushes out the problem above that manifested itself in 20+ or so tests. However, it does not do so reliably. The previous problem appears pretty often, but it does affect the problem.

        <Test()> _
        Public Sub TTest()
            Dim CName As String = "testEbc"
            Dim serviceName As String = "testService"
            Dim businessMock As MockObject
            Dim businessService As BusinessService
            SyncLock (Me)
                If businessMock Is Nothing Or businessService Is Nothing Then
                    businessMock = MockManager.MockObject(GetType(BusinessService))
                    businessMock.Strict = True
                    businessMock.StrictStatic = True

                    businessMock.AlwaysReturn("GetCName", CName)
                    businessMock.AlwaysReturn("GetServiceName", serviceName)

                    businessMock.ExpectConstructor()
                    businessService = CType(businessMock.Object, BusinessService)
                    Debug.Assert(businessService.GetCName() = CName, "Service should return name as setup")
                End If
            End SyncLock
        End Sub



(The other downside is that I seem to get the magic TypeInitializer exception more often.)

This is pretty scary, but I have to get it to work, somehow.
answered by mawi (2k points)
0 votes
I am not really sure what exactly is happening in your code.
But it seems that you are keeping a mock as a member field, this can lead to several problems.
This can be caused by using MockManger.Verify() or MockManager.Init() , this will reset the mocks and leave you with a 'dangling' mock.

The best way to do this is to use: MockManager.GetInstanceMocks().

Perhaps we should create an API to check if the mocked object is dangleing or not.
answered by scott (32k points)
0 votes
Hi again scott!

you mean that I may have called init/verify but rely on mocks created before that?

I am thinking more the other way, that somehow some mocks from before an init are hanging around and interfering.

(My init/verify is trying to iron away all possible leftovers, though.)
answered by mawi (2k points)
0 votes
Hi,
Can you run the TypeMock Tracer?

You will be able to see what instances are mocked.
In the tracer, clicking on a mock instance will show the calls made on it,
and clicking on a call will show what mock it was made on.

This might give us a better idea what is happening as I cannot seem to recreate the problem.
answered by scott (32k points)
0 votes
I have isolated all mocking and no longer use any helper instances and the problem goes away. Since it now works I cannot honestly say that I am without guilt.

At the same time, the behavior exhibited by TTest should not be affected by anything else (see the code posted above). In that piece of code there are nothing but local references, I reiterate the code here (with some cleanup):

<Test()> _
Public Sub TTest()
    MockManager.Init()
    Dim CName As String = "testEbc"
    Dim serviceName As String = "testService"
    Dim businessMock As MockObject
    Dim businessService As BusinessService
    businessMock = MockManager.MockObject(GetType(BusinessService))
    businessMock.Strict = True
    businessMock.StrictStatic = True

    businessMock.AlwaysReturn("GetCName", CName)
    businessMock.AlwaysReturn("GetServiceName", serviceName)

    businessMock.ExpectConstructor()
    businessService = CType(businessMock.Object, BusinessService)
    Debug.Assert(businessService.GetCName() = CName, "Service should return name as setup")
    MockManager.Verify()
End Sub


This test should not be affected by anything else, AFAICS. Yet it clearly was.

It would be interesting to dig deeper and not work around but find out what causes these dependencies.

It does "feel" like there is at times some state lingering on even efter verify/inits have been issued.

If I get a chance I will devote some time to this. The reason for my interest is that I am sticking my neck out in my current project, pushing for Typemock as the first project at this corporation. I will also be talking about working with "legacy code" using testsupport in a couple of weeks so it would be nice to talk about TypeMock at that time.

Anyhow, thanks for your time.
answered by mawi (2k points)
0 votes
Hi Marcus,

I have seen this behaviour at times, it is always because of a Verify() not being called.
i.e. The Test Fails and throws an exception and the verify is not called.
This is one of the reasons that the Tracer was created - to find and debug these cases.

The reason for my interest is that I am sticking my neck out in my current project, pushing for Typemock as the first project at this corporation. I will also be talking about working with "legacy code" using testsupport in a couple of weeks so it would be nice to talk about TypeMock at that time.


:wink: Good Luck, I have seen many companies choose TypeMock.NET, at the end it saves loads of time and allows for previously untestable code to be tested.
answered by scott (32k points)
...