Mocking many methods at once

1,236 views
Skip to first unread message

Gili

unread,
Oct 26, 2008, 7:39:22 PM10/26/08
to mockito
Hi,

I am trying to mock the following method invocations:

UriInfo.getAbsolutePathBuilder()).path(Administrators.class,
"getAdministrator").build(Mockito.anyCollection()).thenReturn(result);

I've had to break it down into multiple mocking calls. For example:

UriBuilder uriBuilder = Mockito.mock(UriBuilder.class);
Mockito.when(uri.getAbsolutePathBuilder()).thenReturn(uriBuilder);

Mockito.when(uriBuilder.path(Administrators.class,
"getAdministrator")).thenReturn(uriBuilder);

Mockito.when(uriBuilder.build(Mockito.anyCollection())).thenReturn(result);

Is there an easier way or is my approach the best we can do for now?

Thanks,
Gili

szczepiq

unread,
Oct 27, 2008, 5:36:50 AM10/27/08
to moc...@googlegroups.com

Gili

unread,
Oct 27, 2008, 1:08:25 PM10/27/08
to mockito
I don't necessarily agree with Per's suggestions. He's essentially
saying that if the mocking framework makes it difficult to mock a
certain sequence of method calls then you should rework the underlying
code to make it easier to mock. It is debatable whether this makes
your underlying code any cleaner (he seem to believe so). I think the
mocking framework should be able to just handle existing code.

Gili

On Oct 27, 5:36 am, szczepiq <szcze...@gmail.com> wrote:
> Hi,
>
> Unfortunately, there is no easier way. Have look here:http://groups.google.com/group/mockito/browse_thread/thread/2f8b0e17d...
>
> Cheers,
> Szczepan Faber

CowOfDoom

unread,
Oct 27, 2008, 1:58:16 PM10/27/08
to mockito
Well, a lot of people on the Mockito board naturally take a "mockist"
approach to testing. There's certainly nothing wrong with that
approach, but to a mockist there's nothing worse than a succession of
method invocations. Still, this strong adherence can be taken too
far. To quote Martin Fowler:

Mockist testers do talk more about avoiding 'train wrecks' - method
chains of style of getThis().getThat().getTheOther(). Avoiding method
chains is also known as following the Law of Demeter. While method
chains are a smell, the opposite problem of middle men objects bloated
with forwarding methods is also a smell. (I've always felt I'd be more
comfortable with the Law of Demeter if it were called the Suggestion
of Demeter.)
- http://martinfowler.com/articles/mocksArentStubs.html

Gili Tzabari

unread,
Oct 27, 2008, 2:12:38 PM10/27/08
to moc...@googlegroups.com

That's exactly the way I feel! I'm not fan of method chains either,
but there are definite places where they belong, such as the Builder
design pattern. Also, I prefer having at most one way to do anything in
my API.

Most of my code conforms to the so-called "Law Of Demeter" but there
are some places that do not and I feel quite comfortable defending those
design decisions. Method chains can be abused, but they are not always
abusive.

Gili

szczepiq

unread,
Oct 28, 2008, 4:53:52 AM10/28/08
to moc...@googlegroups.com
Hi,

>There are some places that do not and I feel quite comfortable defending those
>design decisions.

Method chains happen but usually when I interrogate some data object
and I'm only interested in it's state. No mocking needed. I would just
create this object. Something like this:

//code:
article.getAuthor().getName();
//test:
articleBuilder().authorName("John").toArticle();

Going back to your example with UriBuilder. Isn't this class mocked in
many places in your test codebase? Isn't it mocked in similar way all
the time, eg: Hey UriBuilder, give me *this uri* if someone asks. It
might be nicer to use real UriBuilder or a hand stub, so you can do
this: new UriBuilder("http://google.com")?

Finally going back to Mockito and your feature request - it's going to
be very hard to implement it with when() API - due to the fact mocks
mostly return nulls by default. You might try to hack it into
doReturn() API then show us examples how you used it.

Cheers,
Szczepan Faber

Gili

unread,
Oct 28, 2008, 12:13:29 PM10/28/08
to mockito
It's a nice idea but it doesn't come out so clean for my use-case.
Currently I have:

private UriInfo uriInfo;
private UriBuilder uriBuilder;

private void stubMethodPath(String method, URI result)
{

Mockito.when(uriInfo.getAbsolutePathBuilder()).thenReturn(uriBuilder);
Mockito.when(uriBuilder.path(Administrators.class,
method)).thenReturn(uriBuilder);

Mockito.when(uriBuilder.build(Mockito.anyCollection())).thenReturn(result);
}

If I replace this with a UriInfoBuilder then I will need to somehow
return *both* UriInfo and UriBuilder from the builder in order to be
able to verify() both. You can't invoke verify() before the actual
test runs right?

Gili

On Oct 28, 4:53 am, szczepiq <szcze...@gmail.com> wrote:
> Hi,
>
> >There are some places that do not and I feel quite comfortable defending those
> >design decisions.
>
> Method chains happen but usually when I interrogate some data object
> and I'm only interested in it's state. No mocking needed. I would just
> create this object. Something like this:
>
> //code:
> article.getAuthor().getName();
> //test:
> articleBuilder().authorName("John").toArticle();
>
> Going back to your example with UriBuilder. Isn't this class mocked in
> many places in your test codebase? Isn't it mocked in similar way all
> the time, eg: Hey UriBuilder, give me *this uri* if someone asks. It
> might be nicer to use real UriBuilder or a hand stub, so you can do
> this: new UriBuilder("http://google.com")?
>
> Finally going back to Mockito and your feature request - it's going to
> be very hard to implement it with when() API - due to the fact mocks
> mostly return nulls by default. You might try to hack it into
> doReturn() API then show us examples how you used it.
>
> Cheers,
> Szczepan Faber
>
> On Mon, Oct 27, 2008 at 7:12 PM, Gili Tzabari <gili.tzab...@gmail.com> wrote:
>
> >    That's exactly the way I feel! I'm not fan of method chains either,
> > but there are definite places where they belong, such as the Builder
> > design pattern. Also, I prefer having at most one way to do anything in
> > my API.
>
> >    Most of my code conforms to the so-called "Law Of Demeter" but there
> > are some places that do not and I feel quite comfortable defending those
> > design decisions. Method chains can be abused, but they are not always
> > abusive.
>
> > Gili
>
> > CowOfDoom wrote:
> >> Well, a lot of people on the Mockito board naturally take a "mockist"
> >> approach to testing.  There's certainly nothing wrong with that
> >> approach, but to a mockist there's nothing worse than a succession of
> >> method invocations.  Still, this strong adherence can be taken too
> >> far.  To quote Martin Fowler:
>
> >> Mockist testers do talk more about avoiding 'train wrecks' - method
> >> chains of style of getThis().getThat().getTheOther(). Avoiding method
> >> chains is also known as following the Law of Demeter. While method
> >> chains are a smell, the opposite problem of middle men objects bloated
> >> with forwarding methods is also a smell. (I've always felt I'd be more
> >> comfortable with the Law of Demeter if it were called the Suggestion
> >> of Demeter.)
> >> -http://martinfowler.com/articles/mocksArentStubs.html

szczepiq

unread,
Oct 28, 2008, 6:12:58 PM10/28/08
to moc...@googlegroups.com
> If I replace this with a UriInfoBuilder then I will need to somehow
> return *both* UriInfo and UriBuilder from the builder in order to be
> able to verify() both. You can't invoke verify() before the actual
> test runs right?

Well, I thought about hand mock really, without exercising mockito.

Cheers,
Szczepan Faber

Reply all
Reply to author
Forward
0 new messages