13

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?

Tor Haugen
  • 19,509
  • 9
  • 45
  • 63
  • a little bit OT but how does the callee consume an anonymous-typed object ? I've never seen such a use-case. Just tryin to review the choice of a generic method here.. – Gishu Jun 01 '11 at 06:47
  • Good question ;) The point is not for the Report method to do anything with the argument, just to return it. It facilitates chaining in our LINQ expressions. As such, we can certainly rewrite it, but thought we'd have a go. – Tor Haugen Jun 03 '11 at 10:55
  • 2
    that said. If you create another anonymous type with the same order and type of properties, they should be of the same type. Maybe that can help you .. create a similar dummy type in your test and do a GetType() on it to retrieve the type... but like I said earlier.. looks intricate/clever. Simple is preferred :) – Gishu Jun 03 '11 at 11:34
  • @Gishu - Hey, that's interesting. It would have the *same* type? I'll certainly take a closer look at that. – Tor Haugen Jun 06 '11 at 11:13
  • Confirmed.. http://msdn.microsoft.com/en-us/library/bb397696.aspx See Remarks section - Para#2 – Gishu Jun 07 '11 at 02:40

2 Answers2

6

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
}
Jaider
  • 14,268
  • 5
  • 75
  • 82
IndigoDelta
  • 1,481
  • 9
  • 11
0

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;
    }
}
Stefan Steinegger
  • 63,782
  • 15
  • 129
  • 193