Steve K wrote:
I don't know if this will help you, but I've been experimenting with using the CocoonBean in my test cases. You could create a subclass of the CocoonBean class that will expose the getComponentManager() method to your test case. You could then use that method to create and test the component.

Thank you, but I already have a ComponentManager provided by ExcaliburTestCase, however what I need is a ServiceManager.


Anyway, after some thinking I came to the conclusion that the class I want to test (o.a.c.woody.datatype.DynamicSelectionList) does not need either a ComponentManager or a ServiceManager. Its generateSaxFragment method should be passed a Source and should not get one from a SourceResolver that in turn it gets from a ServiceManager:

public void generateSaxFragment(ContentHandler contentHandler, Locale locale, Source source) throws ProcessingException, SAXException, IOException {
SelectionListHandler handler = new SelectionListHandler(locale);
handler.setContentHandler(contentHandler);
SourceUtil.toSAX(source, handler);
}


Why? Well, because, according to the Law of Demeter ([1]), any method of an object should call only methods belonging to:

- itself
- any parameters that were passed in to the method
- any objects it created
- any directly held component objects.

The current implementation of generateSaxFragment violates this law by calling a method on an object (Source) returned by a method called on an object (SourceResolver) returned by a method called on a directly held object (ServiceManager): two levels of indirection more than necessary. This creates a tight and unnecessary coupling between DynamicSelectionList, SourceResolver and ServiceManager.

By refactoring the way I plan to, we get the added benefit that we can get a Source from wherever we like, be it a ComponentManager or a ServiceManager or maybe some mock implementation, easing testability.

What do you people think?

Ugo

[1]: http://www.ccs.neu.edu/home/lieber/LoD.html



Reply via email to