Mocking void methods

5,480 views
Skip to first unread message

Richard Banks

unread,
Jul 5, 2010, 5:28:39 AM7/5/10
to NSubstitute
If a method has a return value I can do this:

aMock.SomeMethod.Returns(args => doSomething());

but if the method is has a Void return value then the Returns() option
isn't available to me. Probably because it's an Action instead of a
Func that needs to be applied.

I'm assuming you just haven't bumped into that yet?

-- Richard

Xerxes

unread,
Jul 5, 2010, 5:43:55 AM7/5/10
to NSubstitute
maybe i misunderstood something but if the method has a void return,
why would you want to set the Returns() on it?

Xerxes

unread,
Jul 5, 2010, 5:47:29 AM7/5/10
to NSubstitute
more specifically - any method "returning" void, isnt actually
returning
anything, so the Returns doesnt apply anyway.

On Jul 5, 7:28 pm, Richard Banks <rbank...@gmail.com> wrote:

David Tchepak

unread,
Jul 5, 2010, 5:48:52 AM7/5/10
to nsubs...@googlegroups.com
Hi Richard,

We don't support Returns() on void methods because, well, because they can't return anything. :)

You raise a good point about performing an action when a void method is called though, which we do support. Adapting your example:

        [Test]
        public void VoidMethods() {
            var aSub = Substitute.For<SomeInterface>();
            aSub.When(x => x.SomeVoidMethod()).Do(x => DoSomething());

            aSub.SomeVoidMethod();
            Assert.True(_wasSomethingDone);
        }

        private void DoSomething() {
            _wasSomethingDone = true;
        }

Not quite as nice as some of the other NSub syntax, but we're hoping it's not something people will need too frequently and so won't give too much friction. 

(Btw, I'd be keen to hear any ideas for an alternative syntax, so please ping me if you come up with something. :))

Cheers,
David



--
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.


Richard Banks

unread,
Jul 5, 2010, 5:51:31 AM7/5/10
to nsubs...@googlegroups.com
So I can override it's behaviour.  Basically like the .Do() method in Rhino.

--
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.




--
- Richard Banks (@rbanks54)
blog: http://www.richard-banks.org
podcast: http://www.talkingshopdownunder.com

Richard Banks

unread,
Jul 5, 2010, 5:52:43 AM7/5/10
to nsubs...@googlegroups.com
Ah.  Ok.  I didn't notice the When in the intellisense list.

Thanks :-)

P.S. For alternate syntax how about

aSub.SomeVoidMethod().Do((x,y,z) => SomethingHere(x,y,z));

David Tchepak

unread,
Jul 5, 2010, 5:55:35 AM7/5/10
to nsubs...@googlegroups.com
That would be our preferred syntax, but unfortunately System.Void is not a first class citizen in C#, so we can't put an extension method on it to make it work. 

(SomeVoidMethod() returns void, so can't do anything with that return. Hence resorting to lambdas.)

Richard Banks

unread,
Jul 5, 2010, 6:09:47 AM7/5/10
to nsubs...@googlegroups.com
Bummer. :-(

Garth Kidd

unread,
Aug 2, 2010, 12:42:36 AM8/2/10
to NSubstitute
David, I'd appreciate a way to get an Action matching the signature of
my void method. I could then use it to call methods on the void
method's arguments.

A simplification of my current problem:

public interface IMaintainIndexes {
void RegisterIndex<T>(Predicate<T> criterion);
}

public interface IRegisterIndexes {
void RegisterIndexes(IMaintainIndexes indexer);
}

[TestFixture]
public void TestsIndexer() {
[Test]
public void CriteriaIsCalled() {
bool wasCalled = false;
var indexer = new ConcreteIndexer();
var definer = Substitute.For(IRegisterIndexes);
Func<object, bool> criterion = {
wasCalled = true;
return false;
};

// OnCallOf returns dynamic to achieve the following
definer.OnCallOf.RegisterIndexes(indexer =>
indexer.RegisterIndex<object>(criterion));

indexer.Add(new object());

// WasCalled returns dynamic, too…
definer.WasCalled.RegisterIndexes;
Assert.True(wasCalled);
}
}

The trick is that ConcreteIndexer does not implement IMaintainIndexes.
I might refactor my way around that; I did it to myself because I was
spending too much time fighting one behaviour of generics. It just
occurred to me there's a much simpler way…

Yours,
Garth.

David Tchepak

unread,
Aug 3, 2010, 8:30:13 AM8/3/10
to nsubs...@googlegroups.com
Hi Garth,

We're trying to avoid taking a dependency on .NET 4/dynamic at this stage, but we'll see what we can do for later releases.

With regards to your current problem, I'm not exactly sure what you're trying to achieve. If you can give me a bit more detail on what behaviour you're trying to test I'm happy to try and help out (message me off list if you like).

Regards,
David

Louis Haußknecht

unread,
Aug 24, 2010, 9:17:51 AM8/24/10
to NSubstitute
Hi,

is this also the recommended way to throw an exception when calling a
void - method?

Cheers,

Louis
> > nsubstitute...@googlegroups.com<nsubstitute%2Bunsubscribe@googlegr oups.com>
> > .

David Tchepak

unread,
Aug 24, 2010, 9:36:53 AM8/24/10
to nsubs...@googlegroups.com
Hi Louis,

Yes, just replace DoSomething() in the example below with "throw new FooException()".

Regards,
David

To unsubscribe from this group, send email to nsubstitute...@googlegroups.com.

Louis Haußknecht

unread,
Aug 24, 2010, 9:47:30 AM8/24/10
to NSubstitute
Okay,

so I'm throwing an exception when my void method is called.

That's working so far, but ReceivedWithAnyArgs for the same method
reports, it was not called.

Is this behavior desired?

Louis

David Tchepak

unread,
Aug 24, 2010, 4:53:35 PM8/24/10
to nsubs...@googlegroups.com
Hi Louis,

Are you using the latest release? This should be fixed in 0.1.3. (http://github.com/nsubstitute/NSubstitute/downloads)

If you have the latest release please let me know and we'll get it fixed. (If you can post a failing test case that would be great!)

Regards,
David

To unsubscribe from this group, send email to nsubstitute...@googlegroups.com.

Louis Haußknecht

unread,
Aug 25, 2010, 9:11:13 AM8/25/10
to NSubstitute
Hi David,

it was my fault.

I had to switch to VB 9 in my current project and implemented the
delegate wrong.

Btw, in VB you have to write "sentences" like Substitute.For( of IFoo)
which looks really ulgy....

Thank's for the great work.

Louis

David Tchepak

unread,
Aug 25, 2010, 8:54:40 PM8/25/10
to nsubs...@googlegroups.com
"it was my fault."
Please don't ever blame yourself when you could blame VB. ;)

Do you have any suggestions for syntax that would work with VB? You can call the non-generic version which takes a type array, but I have a feeling that won't help.

To unsubscribe from this group, send email to nsubstitute...@googlegroups.com.

Yann Duran

unread,
Aug 25, 2010, 10:14:10 PM8/25/10
to nsubs...@googlegroups.com
Hi David,
 
I'll ignore your swipe at VB, lol.
 
It's unfortunate that the developers of VB chose to use "of" in generics, but we're used to it I guess, so "Substitute.For(of IFoo)" just registers on the brain as "generics", even though it doesn't read quite as nicely as "Substitute.For<SomeInterface>".
 
Maybe for VB you could have "Substitute.ForType(of IFoo)"?
 
That reads a bit better I guess. Just a thought, although I don't really think a different syntax is all that necessary to be honest. I'm not opposed to it, I just wouldn't be jumping up & down in horror at having to use the current syntax.
 
Great product btw!
 
Yann

David Tchepak

unread,
Aug 25, 2010, 11:09:18 PM8/25/10
to nsubs...@googlegroups.com
Thanks for the feedback Yann. I'd prefer not to add more methods to the API if VBers are happy enough with the current syntax.

Cheers,
David

Louis Haußknecht

unread,
Aug 26, 2010, 6:07:04 AM8/26/10
to NSubstitute
I second that.

Please don't pullute the nice syntax just for VB!

Working in VB is almost always troublesome if you want to use most of
the fluent stuff with Labda's etc.

Louis


On 26 Aug., 05:09, David Tchepak <tche...@gmail.com> wrote:
> Thanks for the feedback Yann. I'd prefer not to add more methods to the API
> if VBers are happy enough with the current syntax.
>
> Cheers,
> David
>
>
>
> On Thu, Aug 26, 2010 at 12:14 PM, Yann Duran <yanndu...@gmail.com> wrote:
> >  Hi David,
>
> > I'll ignore your swipe at VB, lol.
>
> > It's unfortunate that the developers of VB chose to use "of" in generics,
> > but we're used to it I guess, so "Substitute.For(of IFoo)" just registers
> > on the brain as "generics", even though it doesn't read quite as nicely as "
> > Substitute.For<SomeInterface>".
>
> > Maybe for VB you could have "Substitute.ForType(of IFoo)"?
>
> > That reads a bit better I guess. Just a thought, although I don't really
> > think a different syntax is all that necessary to be honest. I'm not opposed
> > to it, I just wouldn't be jumping up & down in horror at having to use the
> > current syntax.
>
> > Great product btw!
>
> > Yann
>
> >  *From:* David Tchepak <tche...@gmail.com>
> > *Sent:* Thursday, August 26, 2010 10:54 AM
> > *To:* nsubs...@googlegroups.com
> > *Subject:* Re: [nsubstitute] Re: Mocking void methods

David Tchepak

unread,
Aug 26, 2010, 8:51:32 AM8/26/10
to nsubs...@googlegroups.com
Could always have a NSubstitute.VbSupport namespace with VB-specific methods. :)

To unsubscribe from this group, send email to nsubstitute...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages