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?) |