Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / DevOps / testing

Reflection: Subtle Difference between Moq Vs. RhinoMocks

4.20/5 (2 votes)
15 Sep 2015CPOL1 min read 16.3K  
While writing tests for methods that use .NET Reflection, I found out that Rhino doesn't expose stubbed method for reflected invocation.

Introduction

While writing tests for methods that use .NET Reflection, I found out the Rhino proxy doesn't expose stubbed methods while using reflection. However, Moq, does support such use case.

Background

TDD is very important when it comes to writing libraries or methods that use reflection due to the code being a bit fragile using reflection, given the fact that 90% of the time, you won't get compile time errors. Writing tests that would greatly help spot breaking changes to libraries that would only appear in runtime

Mocked Interface

To demonstrate this difference, I've written a simple test code for a basic interface IAnInterface having the following definition:

C#
interface IAnInterface
    {
        bool Get(int Id);
        void Process();
    }

Writing the Test in RhinoMocks

Writing the following test in RhinoMocks causes a NullReferenceException at the invocation of method1. Using a StrictMock doesn't help and of course stubbing the GetType() and GetMethod() methods are not possible since they're not virtual (yes, I foolishly tried that).

C#
[TestMethod]
public void TestingRhino()
{
    var obj = MockRepository.GenerateMock<IAnInterface>();
    obj.Stub(x => x.Get(Arg<int>.Is.Anything)).Return(true);

    var method1 = obj.GetType().GetMethod(nameof(obj.Get));
    var method2 = obj.GetType().GetMethod(nameof(obj.Process));

    //method1 invocation causes NRE since the proxy doesn't expose the methods
    method1.Invoke(obj, new[] {(object) 99});

    method2.Invoke(obj, null);

    obj.AssertWasCalled(x => x.Get(99));
    obj.AssertWasCalled(x => x.Process());
}

Writing the Test in Moq

Writing the same test in Moq passes the tests and successfully invokes the reflected methods.

C#
[TestMethod]
public void TestingMoq()
{
    var mock = new Mock<IAnInterface>();
    mock.Setup(x => x.Get(It.IsAny<int>())).Returns(true);

    var obj = mock.Object;

    var method1 = obj.GetType().GetMethod(nameof(obj.Get));
    var method2 = obj.GetType().GetMethod(nameof(obj.Process));

    method1.Invoke(obj, new[] {(object) 99});
    method2.Invoke(obj, null);

    mock.Verify(x => x.Get(99));
    mock.Verify(x => x.Process());
}

Points of Interest

While you might prefer a mocking/stubbing/faking framework for one reason or the other, sometimes you're stuck at things that simply work in one framework vs the other.

I didn't try other frameworks other than the Moq and Rhino. Please state in the comments if it works on your favourite mocking framework.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)