|
From: Barry K. <bk...@in...> - 2002-11-18 15:13:00
|
>
>
>> I don't see how the ExpectationSet can do this. How to specify the
>> mock return value for each key1/key2 combination? Can I use the
>> Constraints with ExpectationSet (for mulitple arguments)?
>
>
> We're still thinking about this one, but it's an obvious direction to go.
Seems that the dynamic mocksobjects handle this quite nicely. Here's
what I did: The class I needed to test was an abstract class, so I could
not use Mock or MockObject directly. Instead I mocked just the abstract
hook methods required to the test the template methods. In the case of
the 'getQuantity' hook method, I did:
private CallSet expectedGetQuantity1 = new CallSet();
// Just to provide an easier setup mechansim than having the test
use the CallSet directly
public void expectGetQuantity(Foo foo, Bar bar, Integer returnValue) {
expectedGetQuantity1.expectReturn(
new Constraint[]{P.eq(foo), P.eq(bar)}, returnValue);
}
public int getQuantity(Foo foo, Bar bar) {
try
return ((Integer) expectedGetQuantity1.call(new
Object[]{foo, bar})).intValue();
} catch (Throwable t) {
// It kinda sucks that call() declares Throwable. Its really
unecessary, since reflection will
// throw the exception of the reflected. If the reflected
method declares an exception
// the mock method can pass it thru (or extract it from the
exception the method.invoke() throws).
throw new RuntimeException(t);
}
}
public void verify() throws AssertionFailedError {
expectedGetQuantity1.verify();
...
}
>>
>> BTW, are there any other examples floating around (ie, projects that
>> make extensive use of mockobjects)? The ones the distribution are ok,
>> but not too extensive.
>
>
> not sure, but you could contribute some
Well, we have over 3000 unit tests for our system. I looked at
mockobjects when we started, but instead decided to use the following
very simple mock idiom (aka simplemock):
interface:
public int getFoo(Bar bar);
mock:
public boolean getFooCalled;
public Integer getFooReturn;
public Bar getFooBar;
public int getFoo(Bar bar) {
getFooCalled = true;
getFooBar = bar;
return getFooReturn.intValue();
}
We have a code generator that creates this simple idiom from interfaces.
One of the big problem we ran into with mockobjects was the ability to
get back the values passed into mocks (vs. just having the mock assert
the values). For example, when testing a class that registers as a
listener [with some mock], we often want to get hold of that listener
instance (which may be the CUT or an inner of class of the CUT) and
invoke methods on the listener so as to test the listening behavior.
Implementations of Expectation all maintain the expected values as
private and provide no accessors, making this type of usage impossible.
On the other hand, testing multiple calls to the mock within a single
test using simplemock is painful. You have to explicity code in support.
eg, Provide a collection for each argument and return values, or create
a custom MockCall abstraction.
Back then I never really dug into the mockobjects code. Now, after
having done so, I see that the mockobjects implementation is clean and
simple, and most of limitations [for us] can easiliy be removed. We used
easymock for a while, but had same issues as with mockobjects.
As for contributing. I certainly will. Both to the core and dynamic
modules, and examples as we incrementally convert.
Thanks for the help Steve.
-bk
(I notice that all your responses post to both user and dev. Should that
be the normal practice?)
|