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'm having trouble mocking a generic method on a static class. The class and method I'm trying to mock look as such:

public static class AgentFactory
{
        private static Dictionary<string, IAgent> _agentDictionary;

        static AgentFactory()
        {
            _agentDictionary = new Dictionary<string, IAgent>();
        }

        public static T GetAgent<T>() where T : IAgent
        {
            if (!_agentDictionary.ContainsKey(typeof(T).Name))
            {
                _agentDictionary.Add(typeof(T).Name, LoadAgent<T>());
            }
            return (T)_agentDictionary[typeof(T).Name];
        }
}


I'm trying to mock the GetAgent<T> method so that it returns an instance of another mock I've created:

[TestFixture]
public class AccountAgentTests
{
    private Mock _agentFactoryMock;
    private MockObject _accountAgentMock;

    [SetUp]
    public void Setup()
    {
        _agentFactoryMock = MockManager.Mock(typeof(AgentFactory));
        _accountAgentMock = MockManager.MockObject(typeof(IAccountAgent));

        _agentFactoryMock.ExpectAndReturn("GetAgent", _accountAgentMock.MockedInstance, typeof(IAccountAgent));

        [... set up other mocks here ...]
    }
}


When I run this though, TypeMock throws an exception, complaining about the return type of the generic method call:

------ Test started: Assembly: MyCompany.AccountAgent.UnitTests.dll ------

TestCase 'MyCompany.AccountAgent.UnitTests.AccountAgentTests.MyUnitTest'

failed: TypeMock.TypeMockException : 

*** Method GetAgent in type MyCompany.Agent.Factory.AgentFactory returns  and not TypeMock.Mock+a.
       at w.b(Type A_0, String A_1, Type A_2, Type[] A_3)
       at TypeMock.Mock.a(String A_0, Object A_1, Boolean A_2, Boolean A_3, Int32 A_4, Type[] A_5)
       at TypeMock.Mock.ExpectAndReturn(String method, Object ret, Int32 timesToRun, Type[] genericTypes)
       at TypeMock.Mock.ExpectAndReturn(String method, Object ret, Type[] genericTypes)
       MyCompanyAccountAgentUnitTestsAccountAgentTests.cs(38,0): at MyCompany.AccountAgent.UnitTests.AccountAgentTests.Setup()


Line 38 in the error message corresponds to the 'ExpectAndReturn' line above.

I'm using TypeMock Isolator 4.2.4; I recently upgraded from 4.1.0 (the above code worked fine in 4.1.0, but I had other problems with mocking 'ref' parameters).

Any help appreciated -

Thanks,
Nick
asked by zcrar70 (2.9k points)

3 Answers

0 votes
Hi Nick,

I've tried reproducing your problem here but for some reason the test keep on passing OK. This may relate to the fact that Ive had to fill in some missing blanks so i might not be seeing your exact case

Anyway, try replacing the ExpectAndReturn line with this:
_agentFactoryMock.ExpectAndReturn("GetAgent", _accountAgentMock.Object);

and tell me if this helped or not.

also try looking at the value of _accountAgentMock.MockedInstance at the time of the setup. It might be set to null and this will trigger such an error (BTW that was an unrelated issue that we solved not too long ago)

I'm also attaching the entire sample code I've used you might be able to glimpse some difference that may explain why this passes on my end.

If all else fails, we will probably need to "fleshen" out a complete example that we can try and work with to see what exactly fails. (Let me know if you want to take it offline at that stage)
answered by lior (13.2k points)
0 votes
Hi Lior,

thanks for the response, and apologies for taking a couple of days to follow this up.

I just copied these tests over from my co-workers' machine (which we were using to write the tests) over to mine, and the tests now seem to run as expected without any changes. I suspect this may have something to do with how we set up our references: we reference the Typemock.DLL from a folder relative to the Visual Studio project root. In my case, I have the same version of Typemock installed on my box (using the .msi installer) as is referenced in the project (4.2.4); in my co-worker's case, he still has 4.1 installed locally, whereas the project uses the latest version. Is this likely to cause this type of problem?

Incidentally, the test passes using either '_accountAgentMock.Object' or '_accountAgentMock.MockedInstance'. Out of curiosity, what is the difference between those two properties? The API docs aren't very clear on this.

Many thanks,
Nick
answered by zcrar70 (2.9k points)
0 votes
Hi Nick,

Actually I'm not 100% sure, but this kind of setup may be the cause of the problem.However it can be simply fixed by just readding the reference on you co-worker machine.

However, there were several fixes related to the working of generic methods between 4.10 and 4.2.4, so it might be best to just upgrade to 4.2.4 just in case.

Practically, when using MockObject API there is no difference between Object and MockedInstance. However the MockedInstance property is also present on the Mock class API and there it behaves differently. It is initialized only after the "real" instance is created later on in the code.
Therefore I recommend the usage of the Object property to prevent the confusing that might arise.
answered by lior (13.2k points)
...