I've used com.mockobjects... ( http://www.mockobjects.com/FrontPage.html ) the most and had good experience. Played with jMock some, and like some of their ideas a lot, but not enough to have a strong opinion. It is quite different.

A couple things I have found using the dynamic proxy based mock object libraries:

Don't use a lot of mocks unless you are comfortably decoupling your code to a very high degree.

Don't have mocks return mocks. This is an example of the coupling thing above.

Don't have non-mock's return mocks. See coupling.

Make sure to write very loosely coupled code.

When writing unit tests using mocks, make sure they are really unit tests, not integration tests. I cannot stress this one enough.

=)

I love mocks, but they do force you to decouple.

-Brian

On Jul 23, 2004, at 1:05 PM, Ugo Cei wrote:

In the Cocoon tests one can find a handful of "Mock Objects", for instance in the o.a.c.environment.mocks package. These mocks are used to stub out objects that are hard and/or expensive to create or manipulate, like a Request or Environment. You can carry out a certain number of tests with this kind of mocks, but there are limits. One limit is that you cannot easily set up and test expectations regarding the interaction between the method under test and its "fixture" which can be made up of such mocks. Imagine, for example, that you want to test the connectPipeline method of AbstractProcessingPipeline:

    /**
     * Connect the next component
     */
    protected void connect(Environment environment,
                           XMLProducer producer,
                           XMLConsumer consumer)
    throws ProcessingException {
        XMLProducer next = producer;
        // Connect next component.
        next.setConsumer(consumer);
    }

    /**
     * Connect the XML pipeline.
     */
    protected void connectPipeline(Environment environment)
    throws ProcessingException {
        XMLProducer prev = this.generator;

        Iterator itt = this.transformers.iterator();
        while (itt.hasNext()) {
            Transformer next = (Transformer) itt.next();
            connect(environment, prev, next);
            prev = next;
        }

        // insert the serializer
        connect(environment, prev, this.lastConsumer);
    }

A possible test is verifying that the setConsumer method on the generator is called with the correct argument, like a transformer. How can you do that if the XMLProducer class does not provide a getConsumer method? We could add it, but it would force all implementors to provide an implementation and it would not be possible if the interface in question were from an external library.

What is needed is an implementation of XMLConsumer that provides a way to set an expectation that the setConsumer method will be called and verify if this is indeed the case. Simple stubs do not provide this capability. This is why some people started drawing a line between simple "stubs" and "real mocks". You can read more about this here [1].

Now, implementing mock objects for the interfaces we want to mock is not that hard but is tedious and is better left to tools. There are a couple of Java libraries out there that are meant to be used with JUnit and that we could add to our arsenal:

- jMock         http://www.jmock.org/index.html
- EasyMock      http://www.easymock.org/index.html

What I am asking here is whether someone has experience with the above mentioned frameworks and feels like suggesting one over the other, or maybe a third alternative.

        Thanks in Advance,

                Ugo

[1] http://www.martinfowler.com/articles/mocksArentStubs.html

--
Ugo Cei - http://beblogging.com/




Reply via email to