Search code examples
c#delegatesrhino-mocksstubbing

How to stub a method with out parameter using custom delegate?


I am trying to stub a method that has an out paramteter using RhinoMock's Do method, but I keep getting the message cannot resolve symbol outParam. Here's the stubbing part:

private static void FakeClientsLoading(MyClass fakeClass, IEnumerable<string> clientsToLoad)
{
    fakeClass.Stub(
        x =>
            x.LoadClientsFromDb(Arg<string>.Is.Anything,
                out Arg<object>.Out(null).Dummy))
        .Do(
            new LoadClientsFromDbAction(
                (someString, out outParam ) =>
                    TestHelper.LoadClients(someString, clientsToLoad)));
 }

And here is my custom delegate declaration:

public delegate void LoadClientsFromDbAction(string s, out object outParam);

What I'd like to achieve is to run the test helper method whenever LoadClientsFromDb is invoked. From my understanding outParam should be mapped to whatever is passed as the out parameter to the called method, but it doesn't seem to work this way.


Solution

  • It seems that I have finally found the answer to my question. It turns out that, quoting section 26.3.1 from this link:

    Specifically, a delegate type D is compatible with an anonymous method or lambda-expression L provided:

    If L is a lambda expression that has an implicitly typed parameter list, D has no ref or out parameters.

    This means that you need an explicitly typed parameter list in order to create a lambda with an out parameter.

    That's not all, though. It is still necessary to assign a value to the out parameter upon exiting the anonymous method.

    The final and working code:

    private static void FakeClientsLoading(MyClass fakeClass, IEnumerable<string> clientsToLoad)
    {
        fakeClass.Stub(
            x =>
                x.LoadClientsFromDb(Arg<string>.Is.Anything,
                    out Arg<object>.Out(null).Dummy))
            .Do(
                new LoadClientsFromDbAction(
                    (string someString, out object outParam) =>
                    {
                        outParam = null;
                        TestHelper.LoadClients(someString, clientsToLoad);
                    }
                    ));
    }