Stub void method with behavior

301 views
Skip to first unread message

melody

unread,
Apr 11, 2008, 11:48:41โ€ฏAM4/11/08
to mockito
In EasyMock I have the ability to expect behavior after a void method
called on a mock. In EasyMock it would look something like this:

myMockObject.voidMethod(EasyMock.someMatcher(),
CaptureArgumentMatcher.capture(someIterator));

EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
public Object answer() throws Throwable {
while (someIterator.hasNext()) {
classUnderTest.process(someIterator.next());
}
return null;
}
});

In the above example, I have written custom matcher to capture the
argument passed in to my mock object. I then use this value to produce
some subsequent behavior. In this particular case, I am trying to mock
a bulk/batch processor that will eventually make a callback to my
classUnderTest. What I'm doing here is making the callback myself with
the value passed into the batch processor. Since the batch processor
does lots of database and other stuff I'm not concerned with, it is
necessary to mock it while also producing the callback behavior.

Is there any way to do something similar with Mockito? I only saw the
ability to stubvoid and throw an exception.

szczepiq

unread,
Apr 11, 2008, 12:36:36โ€ฏPM4/11/08
to moc...@googlegroups.com
>Is there any way to do something similar with Mockito? I only saw the
>ability to stubvoid and throw an exception.

No, there is such feature in Mockito. You have to either return value
or throw an exception. Can you please submit a sample of the code
under test so that we can generalize the scenario and evaluate adding
new feature?

Based on my observations of large codebases I was a bit scared of the
way IAnswer was used (e.g. there were better and cleaner ways of
proving that things work). That's why it didn't make it to the API.

As usual, you may consider rolling your own hand written mock to keep
code clean :)

Looking forward to seeing a bit more sample code.

Cheers,
Szczepan Faber

melody

unread,
Apr 11, 2008, 3:08:48โ€ฏPM4/11/08
to mockito
You are right, in this case it would be very easy for me to roll my
own mock. Doing it that way would also make future tests more simple
because they would not need to know how to mock the behavior. So, I do
not have an example where it would be difficult to make a custom mock
to do the callback. If you're still interested I can provide some code
later.

On 11 Apr, 12:36, szczepiq <szcze...@gmail.com> wrote:
> >Is there any way to do something similar with Mockito? I only saw the
> >ability to stubvoid and throw an exception.
>
> No, there is such feature in Mockito. You have to either return value
> or throw an exception. Can you please submit a sample of the code
> under test so that we can generalize the scenario and evaluate adding
> new feature?
>
> Based on my observations of large codebases I was a bit scared of the
> way IAnswer was used (e.g. there were better and cleaner ways of
> proving that things work). That's why it didn't make it to the API.
>
> As usual, you may consider rolling your own hand written mock to keep
> code clean :)
>
> Looking forward to seeing a bit more sample code.
>
> Cheers,
> Szczepan Faber
>

szczepiq

unread,
Apr 12, 2008, 6:33:18โ€ฏPM4/12/08
to moc...@googlegroups.com
I'm glad you considered using own mocks. Regardless of any mocking
tools, there is always a place for hand written mocks.

>If you're still interested I can provide some code
>later.

I will find a sample useful so if it's not a hassle for you...

Cheers,
Szczepan Faber

Steve Freeman

unread,
Apr 16, 2008, 11:54:09โ€ฏAM4/16/08
to moc...@googlegroups.com
Really? I haven't had to write one in years.

S.

On 12 Apr 2008, at 23:33, szczepiq wrote:
>
> I'm glad you considered using own mocks. Regardless of any mocking
> tools, there is always a place for hand written mocks.
>
>> If you're still interested I can provide some code
>> later.
>
> I will find a sample useful so if it's not a hassle for you...

Steve Freeman
http://www.mockobjects.com

Winner of the Agile Alliance Gordon Pask award 2006

szczepiq

unread,
Apr 16, 2008, 2:07:59โ€ฏPM4/16/08
to moc...@googlegroups.com
> Really? I haven't had to write one in years.

Actually, I don't remember writing a mock by hand since we moved to
Mockito. However before that, devs have been writing mocks to avoid
some of the side-effects of existing mock libraries. That's why I
kind of believe that if using mocking library gives me less readable
code, less readable errors or fragile tests then I roll my own mocks.
On the other hand, I succesfully avoid rolling own mocks by writing
code that is easily testable by Mockito.

Cheers,
Szczepan Faber

Steve Freeman

unread,
Apr 17, 2008, 8:56:35โ€ฏAM4/17/08
to moc...@googlegroups.com
I know we've had this discussion before, but it sounds like there's
something more fundamental that's broken with your dev team. It's
really not supposed to be that complicated.

S

On 16 Apr 2008, at 19:07, szczepiq wrote:
>> Really? I haven't had to write one in years.
>

> Actually, I don't remember writing a mock by hand since we moved to
> Mockito. However before that, devs have been writing mocks to avoid
> some of the side-effects of existing mock libraries. That's why I
> kind of believe that if using mocking library gives me less readable
> code, less readable errors or fragile tests then I roll my own mocks.
> On the other hand, I succesfully avoid rolling own mocks by writing
> code that is easily testable by Mockito.

Steve Freeman

szczepiq

unread,
Apr 17, 2008, 1:50:15โ€ฏPM4/17/08
to moc...@googlegroups.com
There is something fundamental broken with existing mocking libraries (IMHO):

-inability to test what I want
-overspecified tests
-unreadable code (has anyone ever tried to answer simple question: why
'mocky' tests look so different from 'normal' tests)
-fragile tests
-unnatural TDD style
-difficult to learn (some)
-obscure verification errors

That's enough for many teams to consciously choose *not to use them*.

And yes, I agree: mocking / mocking libraries really not supposed to
be that complicated.

Cheers
Szczepan Faber

John

unread,
May 29, 2008, 2:47:45โ€ฏPM5/29/08
to mockito
How about mocking a interface hierarchy that utilizes the visitor
pattern. I have a stable hierarchy of classes that accept visitors.
Is it really necessary to roll my own mocks if I want to add behavior
to the accept method that just invokes the correct visit... method?
Below is a trivial example of what I am talking about (my real code
isn't so trivial, but I thought I try to simplify the problem). To
test the Zoo.cage method I need the accept method to work correctly,
the rest of the methods would be eligible for mocking with the
standard stub and verify functionality.

public interface Animal {
void accept(AnimalVisitor visitor);

// Animal methods
}

public interface Monkey extends Animal {
// Monkey methods
}

public interface Elephant extends Animal {
// Elephant methods
}

public class MonkeyImpl implements Monkey {
public void accept(AnimalVisitor visitor) {
visitor.visitMonkey(this);
}
}

public class ElephantImpl implements Elephant {
public void accept(AnimalVisitor visitor) {
visitor.visitElephant(this);
}
}

public class Zoo {
public void cage(Animal animal) {
// Need different behavior for elephants and monkeys
AnimalVisitor v = new AnimalVisitor() {
public void visitMonkey(Monkey monkey) {
// do something with the monkey methods
}

public void visitElephant(Elephant elephant) {
// do something with the elephant methods
}
}
}
}

public interface AnimalVisitor {
void visitMonkey(Monkey monkey);

void visitElephant(Elephant elephant);
}

On Apr 11, 9:36 am, szczepiq <szcze...@gmail.com> wrote:
> >Is there any way to do something similar with Mockito? I only saw the
> >ability to stubvoid and throw an exception.
>
> No, there is such feature in Mockito. You have to either return value
> or throw an exception. Can you please submit a sample of the code
> under test so that we can generalize the scenario and evaluate adding
> new feature?
>
> Based on my observations of large codebases I was a bit scared of the
> way IAnswer was used (e.g. there were better and cleaner ways of
> proving that things work). That's why it didn't make it to the API.
>
> As usual, you may consider rolling your own hand written mock to keep
> code clean :)
>
> Looking forward to seeing a bit more sample code.
>
> Cheers,
> Szczepan Faber
>

szczepiq

unread,
May 29, 2008, 4:19:28โ€ฏPM5/29/08
to moc...@googlegroups.com
Hi,

From your example I don't quite get where is the problem with missing
IAnswer interface. Here is what I did to test cage() method:


static class Zoo {


public void cage(Animal animal) {
// Need different behavior for elephants and monkeys
AnimalVisitor v = new AnimalVisitor() {
public void visitMonkey(Monkey monkey) {

monkey.setName("Bernard");
}

public void visitElephant(Elephant elephant) {
elephant.setAge(200);
}
};

animal.accept(v);
}
}

@Test
public void shouldCageMonkey() {
Zoo zoo = new Zoo();
MonkeyImpl m = new MonkeyImpl();
zoo.cage(m);
assertEquals("Bernard", m.getName());
}

@Test
public void shouldCageElephant() {
Zoo zoo = new Zoo();
ElephantImpl e = new ElephantImpl();
zoo.cage(e);
assertEquals(200, e.getAge());
}


Cheers,
Szczepan Faber

John

unread,
May 29, 2008, 4:25:33โ€ฏPM5/29/08
to mockito
Ah,

In my real example Monkey and Elephant are hard to setup and maintain,
they contain a lot of business login. I'm really trying to isolate
Zoo for testing and passing in the actual implementation of Monkey or
Elephant will make testing Zoo more difficult. I want to mock them so
that I can avoid the behaviour in the implementation classes.

So I really want tests that look like this...

@Test
public void shouldCageMonkey() {
Zoo zoo = new Zoo();
Monkey m= mock(Monkey.class)
stub(m.getName()).toReturn("Bernard");

zoo.cage(m);
assertEquals("Bernard", m.getName());
}

@Test
public void shouldCageElephant() {
Zoo zoo = new Zoo();
Elephant e = mock(Elephant.class)
stub(e.getAge()).toReturn(12);
zoo.cage(e);
assertEquals(200, e.getAge());
}

John

szczepiq

unread,
May 30, 2008, 4:05:47โ€ฏAM5/30/08
to moc...@googlegroups.com
Hi,

If Moneky and Elephant are hard to setup and maintain I would
probably: #1 make them easy to setup (e.g. builders for test
purposes), or #2: maintain examples of Animals (e.g. reference data)
for test purposes) or #3 mock them as you mentioned:

static class Zoo {
public void cage(Animal animal) {
// Need different behavior for elephants and monkeys
AnimalVisitor v = new AnimalVisitor() {
public void visitMonkey(Monkey monkey) {

monkey.haveBananas(2);
}

public void visitElephant(Elephant elephant) {
elephant.haveNuts(20);
}
};

animal.accept(v);
}
}

@Test
public void shouldCageMonkey() {
Zoo zoo = new Zoo();
MonkeyImpl m = new MonkeyImpl();
zoo.cage(m);

verify(m).haveBananas(2);
}

@Test
public void shouldCageElephant() {
Zoo zoo = new Zoo();
ElephantImpl e = new ElephantImpl();
zoo.cage(e);

verify(e).haveNuts(20);
}

So then, where in your example would you use generic IAnswer interface
for describing responses?


One thought about your exemplary code:

stub(e.getAge()).toReturn(200);
assertEquals(200, e.getAge());

Above assertion doesn't make much sense - it's testing Mockito framework...

Cheers,
Szczepan Faber

Igor Czechowski

unread,
May 30, 2008, 10:16:08โ€ฏAM5/30/08
to moc...@googlegroups.com
Hi John,

Mockito primary feature is to test interaction. Like any other
"mocking" library it has to provide mock/stub functionality to satisfy
certain interaction testing cases. Mockito, however, tries to keep
mocking/stubbing functionality as simple as possible.

What I see in your examples is, that you don't use Mockito to test
interaction, but you are using stubbing feature, which is to me side
effect of the interaction testing library.

The last example szczepiq provided, proves Zoo.cage interacts with
Monkey.haveBananas. Isn't it what you want to test ?

> static class Zoo {
> public void cage(Animal animal) {
> // Need different behavior for elephants and monkeys
> AnimalVisitor v = new AnimalVisitor() {
> public void visitMonkey(Monkey monkey) {
> monkey.haveBananas(2);
> }
>
> public void visitElephant(Elephant elephant) {
> elephant.haveNuts(20);
> }
> };
>
> animal.accept(v);
> }
> }
>
> @Test
> public void shouldCageMonkey() {
> Zoo zoo = new Zoo();

> Monkey m = mock(Monkey.class);
> zoo.cage(m);
> verify(m).haveBananas(2);
> }
>

Cheers,
Igor

John

unread,
May 30, 2008, 11:09:02โ€ฏAM5/30/08
to mockito
Sorry for the bad example by trying to make things simplier I actually
caused confustion. You are right that my code doesn't make sense.
Let's use yours. Lets assume that haveNuts() and haveBananas are
complex methods and they are unit tested elsewhere.

I'm a little confused about the code that you gave me.

@Test
public void shouldCageElephant() {
Zoo zoo = new Zoo();
ElephantImpl e = new ElephantImpl();
zoo.cage(e);
verify(e).haveNuts(20);
}

The verify only works on method only works on mocks correct? So the
code would need to be:


public void shouldCageElephant() {
Zoo zoo = new Zoo();
Elephant e = mock(Elephant.class);
zoo.cage(e);
verify(e).haveNuts(20);
}

Obviously this won't work because the accept method won't call the
correct method on the visitor. That is why I was looking for a way to
stub the accept method.

I apologize in advance if I'm missing something simple

Thanks!
John

szczepiq

unread,
May 30, 2008, 12:22:51โ€ฏPM5/30/08
to moc...@googlegroups.com
Yes, you're right, I somehow missed the obvious fact that accept is
also called on a mock :)

Here is the test I would write. If you prefer to use IAnswer
interface, please write us few lines of code with theoretical test
implementation so we can compare both solutions.

This is my test:

public static class Zoo {
static final class Feeder implements AnimalVisitor {


public void visitMonkey(Monkey monkey) {
monkey.haveBananas(2);
}
public void visitElephant(Elephant elephant) {
elephant.haveNuts(20);
}
}

public void cage(Animal animal) {
AnimalVisitor v = new Feeder();
animal.accept(v);
}
}

Zoo zoo = new Zoo();

Zoo.Feeder f = new Zoo.Feeder();

@Test
public void shouldCageAnimal() {
Animal a = mock(Animal.class);
zoo.cage(a);
verify(a).accept(isA(Zoo.Feeder.class));
}

@Test
public void shouldFeedMonkey() {
Monkey m = mock(Monkey.class);
f.visitMonkey(m);
verify(m).haveBananas(2);
}

@Test
public void shouldFeedElephant() {
Elephant e = mock(Elephant.class);
f.visitElephant(e);
verify(e).haveNuts(20);
}


Cheers,
Szczepan Faber

Jason Sankey

unread,
Jun 12, 2008, 11:26:46โ€ฏAM6/12/08
to mockito
Hi All,

On 11 Apr, 17:36, szczepiq <szcze...@gmail.com> wrote:
> >Is there any way to do something similar with Mockito? I only saw the
> >ability to stubvoid and throw an exception.
>
> No, there is such feature in Mockito. You have to either return value
> or throw an exception. Can you please submit a sample of the code
> under test so that we can generalize the scenario and evaluate adding
> new feature?
>
> Based on my observations of large codebases I was a bit scared of the
> way IAnswer was used (e.g. there were better and cleaner ways of
> proving that things work). That's why it didn't make it to the API.
>
> As usual, you may consider rolling your own hand written mock to keep
> code clean :)
>
> Looking forward to seeing a bit more sample code.

I'm coming in a bit late I know, but I ran into another scenario where
IAnswer (or something similar) would help. Rather than just stubbing
a return value for a method, I needed to stub extra behaviour. In
particular, I wanted to be able to block the stubbed method to test
timeout handling in the code under test. Let me try to explain in
code. My interface to stub is a service interface for a remote
server:

public interface RemoteService
{
int ping();

// Several other service methods.
}

The class under test calls the ping method to determine if the remote
server is contactable, and implements a configurable timeout. When
the ping completes or is timed out, an event is raised indicating the
result. The timeout is enforced regardless of TCP behaviour by
isolating the ping call in a thread and using another thread to wait
for the result for only up to the timeout. A simplified version is
shown below (note the ping call happens in ServicePing.call):

public class PingService
{
...

public void doPing()
{
final Future<PingResult> future =
threadPool.submit(new ServicePing(...));
threadPool.execute(new Runnable()
{
public void run()
{
PingResult result = future.get(getTimeout(),
TimeUnit.SECONDS);
if(result == null)
{
publishEvent(new PingTimeoutEvent(...));
}
else
{
publishEvent(new PingEvent(...));
}
}
}
}
}

So to test this, what I would love to be able to do is be able to
block a call to RemoteService.ping for long enough to simulate a
timeout situation. With something like IAnswer, I could write:

public void testPingTimeout()
{
final Semaphor flag = new Semaphore(0);
RemoteService mockService = mock(RemoteService.class);
stub(mockService.ping()).toReturn(new IAnswer<Integer>()
{
public Integer answer()
{
flag.acquire();
return 1;
}
});

PingService pingService = new PingService();
pingService.setRemoteService(mockService);
pingService.setTimeout(TIMEOUT);
pingService.doPing();

Thread.sleep(TIMEOUT * 2);
flag.release();

assertTimeoutReceived();
}

I have considered a few alternatives, but don't yet have a better
solution. Some points:

- Testing multithreaded code is notoriously difficult, but being able
to isolate down to this level makes it possible. Doing a higher-level
test for this is a lot more complicated (nd probably flakier).
- My example may be complicated, but the same idea could be used for
any test where timing matters.
- IAnswer (or something like it) does add a method to the
(delightfully simple) Mockito API, but it opens up a *lot* of
flexibility in return.
- I am currently using a hand-written mock instead, but it bloats the
test code as the service interface has many methods that are not of
interest to the test. Where I have been able to use Mockito for
larger interfaces the tests are much more compact than with manual
mocks. Sometimes the large interface can (and indeed should) be
broken up, but this is not always practical or desirable.

If you got this far, thanks for your attention :). Any suggestions
for a situation like this are appreciated!

Cheers,
Jason

Felix Leipold

unread,
Jun 12, 2008, 5:49:32โ€ฏPM6/12/08
to moc...@googlegroups.com
Hi Jason,

I had a very similar problem recently and discussed a possible solution with Szczepan. Your implementation really puzzles me a bit. Why do you use another timeout? Why do you use a future+an eventing mechanism. A future is normal used to avoid the asynchronous event thing.

My test looked like this (using a latch):ย ย ย 

public void testNewlySpawnedThreadUsesPingService() {
ย ย ย ย ย ย ย  final CountDownLatch latch = new CountDownLatch(1))
ย ย ย ย ย ย ย  blogPingService = new BlogPingService(new String[0], null){

ย ย ย  ย ย ย  ย ย ย  @Override
ย ย ย  ย ย ย  ย ย ย  public void pingAllServices(BlogPing blogPing) {
ย ย ย  ย ย ย  ย ย ย  ย ย ย  toBeAsserted = blogPing;
ย ย ย  ย ย ย  ย ย ย  ย ย ย  latch.countDown();
ย ย ย  ย ย ย  ย ย ย  }
ย ย ย ย ย ย ย  };

ย ย ย  ย ย ย  BlogPingQueue pingQueue = new BlogPingQueue(blogPingService);

ย ย ย  ย ย ย  pingQueue.enquePingIfBlogPost(newPostt);
ย ย ย  ย ย ย  pingQueue.sendPings();
ย ย ย  ย ย ย  latch.await();
ย ย ย  ย ย ย  assertEquals(new BlogPing(newPost), toBeAsserted);

ย ย ย  }

It does not have to do the timeout thing, even though you could do with a timeout in the latch.await(), because your test might get stuck otherwise ;-).

What I would like to see in Mockito to do this is as follows:

ย ย ย  public void public void testNewlySpawnedThreadUsesPingService() {

ย ย ย ย ย ย ย  blogPingService = mock(BlogPingService.class)
ย ย ย  ย ย ย  BlogPingQueue pingQueue = new BlogPingQueue(blogPingService);

ย ย ย  ย ย ย  pingQueue.enquePingIfBlogPost(newPost);
ย ย ย  ย ย ย  pingQueue.sendPings();
ย ย ย  ย ย ย 
ย ย ย ย  verify(blogPingService,Mockito.awaitOnceWithTimeOut(100)).pingAllServices(Mockito.eq(new BlogPing(contentWithBlogTag)));
ย ย ย  }

Cheers,
Felix

Jason Sankey

unread,
Jun 13, 2008, 6:18:03โ€ฏAM6/13/08
to mockito
Hi Felix,

Thanks for your reply, my responses are inline.

On 12 Jun, 22:49, "Felix Leipold" <felix.leip...@googlemail.com>
wrote:
> I had a very similar problem recently and discussed a possible solution with
> Szczepan. Your implementation really puzzles me a bit. Why do you use
> another timeout? Why do you use a future+an eventing mechanism. A future is
> normal used to avoid the asynchronous event thing.

I am not sure what you mean by "another timeout"? There is only one
timeout in my code - the one in the code under test. The reason for
using a future is not to avoid asynchronicity (did I just invent a
word? :) - it is used so I can enforce a 45 second timeout on the ping
using a time-limited call to get(). Futures just happen to make it
convenient to wait for a limited time for the ping to give their
answer.

> My test looked like this (using a latch):
>
> public void testNewlySpawnedThreadUsesPingService() {
> final CountDownLatch latch = new CountDownLatch(1))
> blogPingService = new BlogPingService(new String[0], null){
>
> @Override
> public void pingAllServices(BlogPing blogPing) {
> toBeAsserted = blogPing;
> latch.countDown();
> }
> };
>
> BlogPingQueue pingQueue = new BlogPingQueue(blogPingService);
>
> pingQueue.enquePingIfBlogPost(newPostt);
> pingQueue.sendPings();
> latch.await();
> assertEquals(new BlogPing(newPost), toBeAsserted);
>
> }
>
> It does not have to do the timeout thing, even though you could do with a
> timeout in the latch.await(), because your test might get stuck otherwise
> ;-).

I see. This actually appears to be the inverse of what I am doing -
the test is blocking and the mock is releasing the latch. In my case
the mock is blocking and the test pauses to verify that the code under
test will timeout. In fact in my case I never need to release the
semaphore at all to verify the timeout happens - I just need to wait
long enough to ensure that the timeout should have tripped.

I note that your scenario could also be solved using an IAnswer-style
API.

> What I would like to see in Mockito to do this is as follows:
>
> public void public void testNewlySpawnedThreadUsesPingService() {
>
> blogPingService = mock(BlogPingService.class)
> BlogPingQueue pingQueue = new BlogPingQueue(blogPingService);
>
> pingQueue.enquePingIfBlogPost(newPost);
> pingQueue.sendPings();
>
> verify(blogPingService,Mockito.awaitOnceWithTimeOut(100)).pingAllServices(Mockito.eq(new
> BlogPing(contentWithBlogTag)));
> }

So you want Mockito itself to test for a timeout? I must admit I am
not sure how this correlates to the original test - unless it is meant
to simulate the same behaviour as if you had included a timeout in
your latch.await() call above?

Cheers,
Jason

szczepiq

unread,
Jun 16, 2008, 8:36:47โ€ฏAM6/16/08
to moc...@googlegroups.com
Hi,

Since I'm a fan of hand made mocks I would rather go for something like this:

public void testPingTimeout()
{
MockRemoteService remoteService = new MockRemoteService();
remoteService.makeUnreachable();

PingService pingService = new PingService();

pingService.setRemoteService(remoteService);
pingService.setTimeout(TIMEOUT);
pingService.doPing();

Thread.sleep(TIMEOUT * 2);
remoteService.makeReachable();

assertTimeoutReceived();
}

instead of IAnser-style:

public void testPingTimeout()
{
final Semaphor flag = new Semaphore(0);
RemoteService mockService = mock(RemoteService.class);
stub(mockService.ping()).toReturn(new IAnswer<Integer>()
{
public Integer answer()
{
flag.acquire();
return 1;
}
});

PingService pingService = new PingService();
pingService.setRemoteService(mockService);
pingService.setTimeout(TIMEOUT);
pingService.doPing();

Thread.sleep(TIMEOUT * 2);
flag.release();

assertTimeoutReceived();
}

The glaring benefit of hand made mock is very good test method
readability. More lines of code with the implementation of
MockRemoteService is an acceptable trade-off but it really depends on
how many test methods use MockRemoteService. If many tests use it then
LOC can go down because there will be less anonymous inner IAnswers.

>I am currently using a hand-written mock instead, but it bloats the
>test code as the service interface has many methods

Would you prefer hand-made mock over IAnswer if the service interface
didn't have many methods?

>Sometimes the large interface can (and indeed should) be
>broken up, but this is not always practical or desirable.

I was about suggest to break up the interface. Also, you can create
'Empty implementation' that can be subclassed easily without
implementing loads of irrelevant methods. However, as you say,
sometimes it might not practical or desirable. Although I'm not keen
on IAnswer feature (and I will never use it :-) I take your points and
I am thinking about including it in Mockito (can I have a patch,
please?).

As far as new verification mode is concerned (Felix' idea) - I'll
think about exposing verification mode so that it can be implemented
by clients.

Thank you guys for your suggestions!
Szczepan Faber

Jason Sankey

unread,
Jun 16, 2008, 1:21:48โ€ฏPM6/16/08
to mockito
Hi Szczepan,
I agree the readability is helped by the ability to add a method with
a meaningful name like "makeUnreachable". But, on the other hand,
when using the IAnswer style the entire code is there in the test
method for the reader to see, if they can handle the verbose inner
class syntax (my brain has adjusted to it :).

If many tests required a hand-written mock then I also agree it would
make sense. But in this case actually all the other tests use simple
Mockito mocks and only this one needs something a bit more powerful.
So the hand written mock I have has no other use than to support this
one test.

> >I am currently using a hand-written mock instead, but it bloats the
> >test code as the service interface has many methods
>
> Would you prefer hand-made mock over IAnswer if the service interface
> didn't have many methods?

Good question. If the hand made mock had more than one use (even if
only a couple) then I would say yes. In the current case I am less
certain: I actually quite like having all the code contained in the
test method.

> >Sometimes the large interface can (and indeed should) be
> >broken up, but this is not always practical or desirable.
>
> I was about suggest to break up the interface. Also, you can create
> 'Empty implementation' that can be subclassed easily without
> implementing loads of irrelevant methods. However, as you say,
> sometimes it might not practical or desirable. Although I'm not keen
> on IAnswer feature (and I will never use it :-) I take your points and
> I am thinking about including it in Mockito (can I have a patch,
> please?).

I think the first thing to consider is definitely whether the large
interface itself is a problem, so I hope people would continue to do
so. Using an empty implementation would work, but it does create an
extra class to maintain. It is not a big deal but I have found this
maintenance annoying in the past as interfaces change.

I am happy to provide a patch for your consideration, I will just need
to get my head around a few bits and pieces first.

> As far as new verification mode is concerned (Felix' idea) - I'll
> think about exposing verification mode so that it can be implemented
> by clients.
>
> Thank you guys for your suggestions!

Thanks for your response and also consideration of this feature.
Hopefully I will have a patch soon and you can decide if it warrants
inclusion in Mockito!

Cheers,
Jason

Steve Freeman

unread,
Jun 18, 2008, 9:26:20โ€ฏAM6/18/08
to moc...@googlegroups.com
I have to say this...

you could always use jMock2 for this test, which includes all this
functionliaty.

S.

szczepiq

unread,
Jun 18, 2008, 10:42:28โ€ฏAM6/18/08
to moc...@googlegroups.com
That's a good idea. For ugly tests use jMock...

Cheers ;)
Szczepan Faber

Jason Sankey

unread,
Jun 19, 2008, 7:57:58โ€ฏPM6/19/08
to mockito
Hi Steve,

On 18 Jun, 14:26, Steve Freeman <smgfree...@gmail.com> wrote:
> I have to say this...
>
> you could always use jMock2 for this test, which includes all this
> functionliaty.

Your point is fair enough in general, but in my case I would prefer
not to use jMock2 for a couple of reasons:

1) I really just want stubbing, not to set "expectations". Although
it is possible to configure relaxed expectations to achieve the same
thing I prefer the mockito method of separating stubbing and
verification in a case like this.
2) We already use two mocking libraries (including mockito): adding a
third is over the top in my opinion. If I could remove the original
mocking library (inferior to both jMock2 and mockito), then it would
be another story.

Thanks,
Jason

Steve Freeman

unread,
Jun 21, 2008, 7:56:49โ€ฏAM6/21/08
to moc...@googlegroups.com
On 20 Jun 2008, at 00:57, Jason Sankey wrote:
> Your point is fair enough in general, but in my case I would prefer
> not to use jMock2 for a couple of reasons:
>
> 1) I really just want stubbing, not to set "expectations". Although
> it is possible to configure relaxed expectations to achieve the same
> thing I prefer the mockito method of separating stubbing and
> verification in a case like this.

For the record, in jMock we have an 'allowing' clause that is the
equivalent of a stub.

> 2) We already use two mocking libraries (including mockito): adding a
> third is over the top in my opinion. If I could remove the original
> mocking library (inferior to both jMock2 and mockito), then it would
> be another story.


point taken...

szczepiq

unread,
Jun 22, 2008, 3:00:53โ€ฏAM6/22/08
to moc...@googlegroups.com
> mocking library (inferior to both jMock2 and mockito), then it would

Just out of interest, what's the inferior lib?

Cheers,
Szczepan

Jason Sankey

unread,
Jun 22, 2008, 6:19:32โ€ฏAM6/22/08
to mockito
On Jun 21, 12:56 pm, Steve Freeman <smgfree...@gmail.com> wrote:
> On 20 Jun 2008, at 00:57, Jason Sankey wrote:
> > 1) I really just want stubbing, not to set "expectations". Although
> > it is possible to configure relaxed expectations to achieve the same
> > thing I prefer the mockito method of separating stubbing and
> > verification in a case like this.
>
> For the record, in jMock we have an 'allowing' clause that is the
> equivalent of a stub.

Thanks for the tip, it may come in handy at a later time.

Cheers,
Jason

Jason Sankey

unread,
Jun 22, 2008, 6:22:56โ€ฏAM6/22/08
to mockito
On Jun 22, 8:00 am, szczepiq <szcze...@gmail.com> wrote:
> > mocking library (inferior to both jMock2 and mockito), then it would
>
> Just out of interest, what's the inferior lib?

It is an old version of DynaMock, which was fine at the time but is
showing its age now. I believe jMock was forked from it way back and
has evolved a lot since then.

Cheers,
Jason

Steve Freeman

unread,
Jun 22, 2008, 11:50:40โ€ฏAM6/22/08
to moc...@googlegroups.com
heavens! There's no way you should still be using that.

S.

John

unread,
Jun 23, 2008, 7:11:13โ€ฏPM6/23/08
to mockito
Hi,

Sorry that it's taken me a while to respond to this. I'd prefer not to
use the solution provided, because it tightly binds the test to the
implementation. A lot of the times we use a visitor strictly as an
implementation decision. Having the test have so much knowledge about
about the implementation makes the test brittle. We often us the
visitor as a replacement for a downcast (to get around some issues
with hibernate proxies), being able to add the behavior to make the
accept method work would save a lot of code and headache.

I'd be willing to try to implement the functionality and submit a
patch if there is a chance that the patch would be accepted.

Thanks!
John
> ...
>
> read more ยป
Reply all
Reply to author
Forward
0 new messages