Rhino Mocks: How to stub a generic method to catch

2019-04-20 12:29发布

问题:

We need to stub a generic method which will be called using an anonymous type as the type parameter. Consider:

interface IProgressReporter
{
    T Report<T>(T progressUpdater);
}

// Unit test arrange:
Func<object, object> returnArg = (x => x);   // we wish to return the argument
_reporter.Stub(x => x.Report<object>(null).IgnoreArguments().Do(returnArg);

This would work if the actual call to .Report<T>() in the method under test was done with object as the type parameter, but in actuality, the method is called with T being an anonymous type. This type is not available outside of the method under test. As a result, the stub is never called.

Is it possible to stub a generic method without specifying the type parameter?

回答1:

I'm not clear on your use case but you might be able to use a helper method to setup the Stub for each test. I don't have RhinoMocks so have been unable to verify if this will work

private void HelperMethod<T>()
{
  Func<object, object> returnArg = (x => x); // or use T in place of object if thats what you require
  _reporter.Stub(x => x.Report<T>(null)).IgnoreArguments().Do(returnArg);
}

Then in your test do:

public void MyTest()
{
   HelperMethod<yourtype>();
   // rest of your test code
}


回答2:

To answer your question: no, it is not possible to stub a generic method without knowing the generic arguments with Rhino. The generic arguments are an essential part of the method signature in Rhino, and there is no "Any".

The easiest way in your case would be to just write a hand written mock class, which provides a dummy implementation of IProgressReporter.

class ProgressReporterMock : IProgressReporter
{
    T Report<T>(T progressUpdater)
    {
      return progressUpdater;
    }
}