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
0 votes
I was attempting to mock some windows management classes. I'm avoiding natural mocks for the moment.

I have been successfully mocking out classes, but problems arose when I was required to return an enumerator on a management collection. Without using natural mocks, is it possible to use 'expectandreturn' to expect a GetEnumerator call and return a mocked version of said enumerator? A colleague of mine did it with natural mocks, but again, I was wanting to accomplish this without natural mocks as a tool for understanding.

The specific classes in question are:

ManagementObjectSearcher
ManagementObjectCollection
ManagementObjectCollection.ManagementObjectEnumerator

the searcher returns the collection and the collection creates the enumerator. I am getting an exception when trying to use this code:

Dim managementobjectsearcherMock As Mock = MockManager.Mock(GetType(ManagementObjectSearcher))

Dim managementobjectcollectionMock As Mock = MockManager.Mock(GetType(ManagementObjectCollection))

Dim managementobjectcollectionenumeratorMock As Mock =         MockManager.Mock(GetType(ManagementObjectCollection.ManagementObjectEnumerator))

managementobjectsearcherMock.ExpectAndReturn("Get", managementobjectcollectionMock)


managementobjectcollectionMock.ExpectAndReturn("GetEnumerator",         managementobjectcollectionenumeratorMock)


This is the exception for the first call:

An unhandled exception of type 'TypeMock.TypeMockException' occurred in TypeMock.dll

Additional information:
*** Method Get in type System.Management.ManagementObjectSearcher has no matching overload that returns TypeMock.MockObject<System.Management.ManagementObjectCollection>.

Any help on this would be most appreciated.
asked by howaldmg (1.9k points)

5 Answers

0 votes
Hi,

What you did in your code is passing the mock controller, instead of the real object to the ExpectAndReturn, that obviously doesn't compile because they are not the correct types.

Try this instead:
        Dim managementobjectsearcherMock As Mock = MockManager.Mock(GetType(ManagementObjectSearcher))
        Dim managementobjectcollectionMock As MockObject = MockManager.MockObject(GetType(ManagementObjectCollection))
        Dim managementobjectcollectionenumeratorMock As MockObject = MockManager.MockObject(GetType(ManagementObjectCollection.ManagementObjectEnumerator))

        managementobjectsearcherMock.ExpectAndReturn("Get", managementobjectcollectionMock.Object)
        managementobjectcollectionMock.ExpectAndReturn("GetEnumerator", managementobjectcollectionenumeratorMock.Object)


Note that the objects I put as return values are MockObject, not Mock. You can read more about the difference here, but the basic rule is that you need a current fake object, which is provided by MockObject to pass as a return value.
answered by gilz (14.5k points)
0 votes
Ok, it's now compiling and running through the test method, but I'm still having trouble with the actual call to the method being tested generating a runtime exception.


An unhandled exception of type 'System.InvalidCastException' occurred in DTAM.exe

Additional information: Unable to cast object of type 'TypeMock.MockObject`1[System.Management.ManagementObject]' to type 'System.Management.ManagementObject'.


This is the actual call that uses the mocked objects in question:

For Each ManagementObject In ManagementObjectSearcher.Get()


I was under the impression that I needed to mock these objects since the enumerator generated is not as general as IEnumerable. Thank you for the quick response!
answered by howaldmg (1.9k points)
0 votes
Hi,
According to the exception you get, it still looks like a MockObject instance is used as a return value instead of its MockObject.Object value.

If you can post the test code along with the function under test, We can try to locate the exact problem.
We can also continue this by email if you prefer.

You can also read the following post in our blog which explain the difference between Mock and MockObject.
answered by lior (13.2k points)
0 votes
Email would be preferable for the sake of confidentiality. For the sake of the board though, when a solution is reached, I would like to post the result for others to find.
answered by howaldmg (1.9k points)
0 votes
Hi Michael,
You've stumbled onto a bug we've realized just this week we have. It's in the way we mock enumerable containers. If you use natural and use a foreach inside the block, everything is recorded correctly and works correctly. With reflective you need to set up everything manually and you don't see all the calls that happen behind the scenes."


I didn't see the response until I tried to reply. Outlook did something strange with your message. Thank you for the explanation. Is there any instance where reflective mocks do something that natural mocks cannot, or is there an instance where reflective mocks might be easier to use?
answered by howaldmg (1.9k points)
...