Since a dummy provides access to its underlying jMock, there is no loss of functionality. But are several benefits to using jDummy, which are detailed in following sections.
If you are concerned about the use of random numbers, please take a look at this note.
With standard jMock, you need to use a cast whenever you access the proxy.
Mock mockFoo = mock(Foo.class); ... frotz((Foo) mockFoo.proxy())
With jDummy, you only cast when you create the jDummy. This makes the interesting part of test code much easier to read.
Foo foo = (Foo) mimicWithDummyValues(Foo.class); ... frotz(foo)
Frequently you need to assert that the result of one invocation will be passed as a parameter to another.
WorkOrder APPROVED_ORDER = (WorkOrder)newDummy(WorkOrder.class); mockApprover.stubs().method("nextApprovedOrder").will(returnValue(APPROVED_ORDER)) mockFulfiller.expects(once()).method("ship").with(same(APPROVED_ORDER))
With jDummy, you don't have to clutter your code creating meaningless dummy data and wiring mocks up to return it:
assertBehavior(fulfiller).expects(once()) .method("ship").with(same(approver.nextApprovedOrder()));
The code that remains is pretty close to the English expression of the method' pre- and post-condtions: the fulfiller's "ship" method will be invoked once with the approver's next approved order.
jDummy unifies the concepts of 'Mock' and 'Dummy'. In fact, mimicWithDummyValues(Order.class) is functionally equivalent to newDummy(Order.class) except that jDummy requires explicit statement of what org.jmock.util.Dummy implicitly asserts:
assertBehavior(dummy).expects(never());
Adding a logging statement like this:
log.info("order total=" + order.getTotal());
will break a test that mocks order and doesn't provide a stub for getTotal(). And adding stubs to the tests to support log statements is not the most productive use of time!
It is very natural with jDummy to start your tests by:
It stands out visually: first come declarations all beginning with a class name, next come all the lines starting with precondition, then all the lines beginning with assertBehavior. This structure is exactly the pattern recommended by expert mockers.
By contrast, novice users of jMock often confuse when to use Mock.expects() and when to use Mock.stubs(). After all, the preconditions do specify the methods you expect to be called during the test. The word expect doesn't sufficiently connote assertion.