H
Havok
I have recently started improve the unit and component tests to an
existing project and I'm finding it a little difficult to test the
components which in turn, use other components. I have a feeling I've
gone around the world to get a working solution and am wondering if
anyone has any better suggestions / examples.
The examples on the jMock homepage involved creating a mock object and
passing it as a parameter. The problem I have is when one component
uses another, it creates the component internally meaning I have no
chance to mock it.
The solution I have used at the moment is to have all components which
create other components (some of these may be in external libs) do so
via a factory class. Whilst running normally the factory class returns
a real instance, and during the jUnit tests the factory can be
configured to return mocks.
I created a factory interface which exposed the components I needed to
create, an abstract class which implemented static setFactory() and
getFactory() methods and keeps the current factory in a static field,
and two concrete classes one which is the real factory, and one which
returns mocks when configured. The reason I created the two factories
is so I can omit the mock factory (and therefore the dependencies on
jUnit and jMock) when I make a distribution.
When a component X creates component Y using the factory it uses a
syntax like this:
ComponentY cy = Factory.getFactory().getComponentY();
When I am in the setUp of a test for componentX I configure the factory
like so:
Factory testFactory = new TestFactory();
Factory.setFactory(testFactory);
Mock mockComponentY = new Mock(ComponentY.class);
testFactory.mockComponent(ComponentY.class, mockComponentY.proxy());
This seems to work fine in practice, but there are some problems.
Firstly I just have a bad feeling about it that I can't put my finger
on. Secondly it leads to an inconsistant way of instantiating classes
since I obviously don't create everything via the factory, just those
which need to be mocked. Thirdly it's trouble to maintain.since I am
adding getComponentXYZ() methods to two classes and an interface every
time I wish to mock a new component.
I suppose the easy solution for the third point would be to do away
with the interface and merge the abstract and real factory classes
together and create a getComponent(Class c) method which creates a
newInstance of the class using reflection, and have the test factory
override that method. Although I think this limits me to components
with 0-argument constructors.
I'm sure a lot of people have done this before so if there is a common
pattern I should be using I'd really appreciate a pointer to it.
Regards, Paul
existing project and I'm finding it a little difficult to test the
components which in turn, use other components. I have a feeling I've
gone around the world to get a working solution and am wondering if
anyone has any better suggestions / examples.
The examples on the jMock homepage involved creating a mock object and
passing it as a parameter. The problem I have is when one component
uses another, it creates the component internally meaning I have no
chance to mock it.
The solution I have used at the moment is to have all components which
create other components (some of these may be in external libs) do so
via a factory class. Whilst running normally the factory class returns
a real instance, and during the jUnit tests the factory can be
configured to return mocks.
I created a factory interface which exposed the components I needed to
create, an abstract class which implemented static setFactory() and
getFactory() methods and keeps the current factory in a static field,
and two concrete classes one which is the real factory, and one which
returns mocks when configured. The reason I created the two factories
is so I can omit the mock factory (and therefore the dependencies on
jUnit and jMock) when I make a distribution.
When a component X creates component Y using the factory it uses a
syntax like this:
ComponentY cy = Factory.getFactory().getComponentY();
When I am in the setUp of a test for componentX I configure the factory
like so:
Factory testFactory = new TestFactory();
Factory.setFactory(testFactory);
Mock mockComponentY = new Mock(ComponentY.class);
testFactory.mockComponent(ComponentY.class, mockComponentY.proxy());
This seems to work fine in practice, but there are some problems.
Firstly I just have a bad feeling about it that I can't put my finger
on. Secondly it leads to an inconsistant way of instantiating classes
since I obviously don't create everything via the factory, just those
which need to be mocked. Thirdly it's trouble to maintain.since I am
adding getComponentXYZ() methods to two classes and an interface every
time I wish to mock a new component.
I suppose the easy solution for the third point would be to do away
with the interface and merge the abstract and real factory classes
together and create a getComponent(Class c) method which creates a
newInstance of the class using reflection, and have the test factory
override that method. Although I think this limits me to components
with 0-argument constructors.
I'm sure a lot of people have done this before so if there is a common
pattern I should be using I'd really appreciate a pointer to it.
Regards, Paul