Search code examples
c#unit-testingreflectionrhino-mocks

RhinoMocks.GenerateMock with generic type, GetGenericArguments is empty


Can anyone shed any light on how I can achieve this with RhinoMocks? I want to create a mock of a generic type (with two TypeParams) and in the code-under test I am calling GetType().GetGenericArguments(), expecting two Types.

e.g. I expect the following test to pass, but it fails:

    [Test]  
    public void Test()
    {
        // Mocking IDictionary<THash, T> fails, but new Dictionary<THash, T> passes
        var myMock = MockRepository.GenerateStub<IDictionary<int, float>>();
        var args = myMock.GetType().GetGenericArguments();
        Assert.That(args, Is.EquivalentTo(new Type[] {typeof(int), typeof(float)}));
    }

Solution

  • You are trying to get the generic arguments for a type that declares none. What you want is to get it from the interface that it implements. This is just a crude example, but it should illustrate the idea for a solution:

    myMock.GetType().GetInterfaces()
        .Single(x => x.Name.Contains("IDictionary")).GetGenericArguments();
    

    Here we're looking for the interface implemented by the mock with the name IDictionary (probably better would be to compare using .GetGenericTypeDefinition against typeof(IDictionary<,>)) and grabbing the generic arguments from it.

    For completeness, here's a more robust (and less stringy) solution (though harder to read):

    myMock.GetType().GetInterfaces()
        .Single(x => x.IsGenericType && 
                     x.GetGenericTypeDefinition() == typeof(IDictionary<,>))
        .GetGenericArguments();