Accessing arguments in a callback

1,049 views
Skip to first unread message

David Keaveny

unread,
Feb 10, 2011, 7:18:58 PM2/10/11
to NSubstitute
First up, seeing as this is my first post to the group, may I say how
much I love NSubstitute? I've always used Moq before, which I thought
had a nice clean syntax, but I still learned to hate the .Object
calls. NSubstitute fixes that and more!

Anyway, on to my question. I have a class under test that has a
dependency on an ILogger interface (which as you would imagine is
basically a wrapper around log4net). During my tests, I want to
capture the calls to the logger, but I'm not too sure how to go about
it. I tried the following:

ILogger Logger = Substitute.For<ILogger>();
Logger
.When(x => x.DebugFormat(CultureInfo.InvariantCulture,
Arg.Any<string>(), Arg.Any<object[]>()))
.Do(x =>
Console.WriteLine(String.Format(CultureInfo.InvariantCulture, x.Args()
[0].ToString(), x.Args()[1])));

MyClass sut = new MyClass(Logger);
sut.Execute();

and hoped that calls to ILogger.DebugFormat would be captured and
written to the console, but I'm not getting anything. Also, am I
capturing the params object[] correctly with Arg.Any<object[]>() ?

David Tchepak

unread,
Feb 10, 2011, 7:34:15 PM2/10/11
to nsubs...@googlegroups.com
Hi David,

You have an off-by-one error in referencing the Args. The following worked for me:

  Console.WriteLine(String.Format(CultureInfo.InvariantCulture, 
        x.Args()[1].ToString(), 
        (object[]) x.Args()[2]))

You could also simplify the When..Do a little using WhenForAnyArgs (assuming you don't want to match the calls on the CultureInfo):

  .WhenForAnyArgs(x => x.DebugFormat(null, null))

Hope this helps. :)

Regards,
Dave



--
You received this message because you are subscribed to the Google Groups "NSubstitute" group.
To post to this group, send email to nsubs...@googlegroups.com.
To unsubscribe from this group, send email to nsubstitute...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/nsubstitute?hl=en.


David Keaveny

unread,
Feb 10, 2011, 7:45:25 PM2/10/11
to NSubstitute
Many thanks for the insanely fast response - your solution works just
fine. I didn't realise that the first argument was captured even if I
specified its value explicitly (not to mention forgetting to cast the
last argument to object[]). Nice to see that It Just Works with params
as well.

Oh, thanks also to Richard Banks for his original blog posting that
compared NSubstitute to its peers; it would have passed under the
radar otherwise.

On Feb 11, 11:34 am, David Tchepak <tche...@gmail.com> wrote:
> Hi David,
>
> You have an off-by-one error in referencing the Args. The following worked
> for me:
>
>   Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
>         x.Args()[1].ToString(),
>         (object[]) x.Args()[2]))
>
> You could also simplify the When..Do a little using WhenForAnyArgs (assuming
> you don't want to match the calls on the CultureInfo):
>
>   .WhenForAnyArgs(x => x.DebugFormat(null, null))
>
> Hope this helps. :)
>
> Regards,
> Dave
>

David Tchepak

unread,
Feb 10, 2011, 7:58:12 PM2/10/11
to nsubs...@googlegroups.com
Yes, the When..Do callback has access to all the arguments the method was called with.

You can also use x.Arg<T>() to return the matching argument of type T (this will fail if there are multiple matching args of that type)

  Console.WriteLine(String.Format(CultureInfo.InvariantCulture, x.Arg<string>(), x.Arg<object[]>()))



Reply all
Reply to author
Forward
0 new messages