gesiod / mockito

Automatically exported from code.google.com/p/mockito
0 stars 0 forks source link

extend stubbing #125

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
The javadoc for when() says: "Stubbing can be overridden: for example common 
stubbing can 
go to fixture setup but the test methods can override it."
The javadoc for reset() warns: "First potential code smell is reset() in the 
middle of the test 
method."

Sure, the overridden scope of when() is one method with one argument match 
while the scope 
of reset() is the complete mock, but doesn't the same argument for not to use 
reset() hold true 
for overriding when() just as well?!? I think there should be at least a 
similar warning in when().

But we have a use case where we'd like a second call to when() not to override 
but to append, 
i.e.:

when(mock.someMethod()).thenReturn("foo").thenReturn("bar");

is the same as

when(mock.someMethod()).thenReturn("foo", "bar");

should be the same as:

when(mock.someMethod()).thenReturn("foo");
when(mock.someMethod()).thenReturn("bar");

The use case is that we want to extract a not-so-simple stubbing to an extra 
method and call 
it multiple times with different arguments (say "foo" and "bar") within a 
single test case.

I know this would be a breaking change; maybe there could be a andWhen() method 
or even 
better given() could be moved from BDDMockito into the Mockito class itself 
where IMHO it 
should go anyway, deprecating when() just as when() deprecated stub()... and 
rename it to 
givenThat, so it reads nicer:

givenThat(mock.someMethod()).willReturn("foo");
givenThat(mock.someMethod()).willReturn("bar");

I have looked a bit at the code: It seems not to be trivial, as the second 
mock.someMethod() 
call happens before the when()/givenThat() call, so it's not easy to 
distinguish it from a call in 
the "//when" part; i.e. it would have to be removed from the 
registeredInvocations, etc.

Original issue reported on code.google.com by snackbo...@googlemail.com on 21 Sep 2009 at 7:52

GoogleCodeExporter commented 8 years ago
Sorry for the late replay but googlecode misbehaves on the occasion and doesn't 
send
notification emails. I accidentally found your entry today ;) 

>I think there should be at least a similar warning in when().

I agree with you. Will change the javadocs

>given() deprecating when()

Thanks for the vote! I'm really tempted to do it for some next release....

>when(mock.someMethod()).thenReturn("foo", "bar");
>should be the same as:
>when(mock.someMethod()).thenReturn("foo");
>when(mock.someMethod()).thenReturn("bar");

If I understand you correctly you want to change the behavior of overriding 
stubbing
into appending stubbing. Correct? 

Lets say we extend the api a little bit:

given(mock.someMethod(1)).willReturn("foo")
.andGiven(mock.someMethod(2)).willReturn("foo")

how does it differ from:

given(mock.someMethod(1)).willReturn("foo")
given(mock.someMethod(2)).willReturn("foo")

Original comment by szcze...@gmail.com on 13 Oct 2009 at 9:06

GoogleCodeExporter commented 8 years ago
With "append to stubbing" I meant appending to the sequence of results for a 
call
with the *same* parameters. We're using Mockito for automated integration 
tests, so
the use case may not be that common, but we have quite complex interactions 
that we
need to stub. Right now we have to collect the interactions by hand only to be 
able
to pass them to Mockito in one go.

Original comment by snackbo...@googlemail.com on 14 Oct 2009 at 7:08

GoogleCodeExporter commented 8 years ago
Oh I see now. Something like:

given(mock.foo()).willReturn(1);
given(mock.foo()).willReturn(2);

mock.foo() -> 1
mock.foo() -> 2
mock.foo() -> 2

Do you realize that we probably cannot just change it as many tests by users 
could
start failing or work incorrectly :(

Do you have any suggestions on how to extend the api?

Original comment by szcze...@gmail.com on 15 Oct 2009 at 8:52

GoogleCodeExporter commented 8 years ago
Exactly!

My first thought for the syntax has been "andWhen", etc.:

given(mock.foo()).willReturn(1);
andGiven(mock.foo()).willReturn(2);

Original comment by snackbo...@googlemail.com on 19 Oct 2009 at 6:58

GoogleCodeExporter commented 8 years ago
andGiven is a bit problematic because it means adding loads of other methods
(andDoReturn...) etc.

Perhaps:

given(mock.foo()).willReturn(1);
and().given(mock.foo()).willReturn(2);

However, I don't think this makes sense. Usually you would like to continue 
stubbing
that was done earlier in the code:

given(mock.foo()).willReturn(1);

...

and().given(mock.foo()).willReturn(2);

So 'and()' is missing a context, right?

Original comment by szcze...@gmail.com on 20 Oct 2009 at 6:11

GoogleCodeExporter commented 8 years ago

Original comment by szcze...@gmail.com on 20 Oct 2009 at 7:07

GoogleCodeExporter commented 8 years ago

Original comment by szcze...@gmail.com on 11 Nov 2009 at 9:07