Mark Brouwer wrote:
Bob Scheifler wrote:
Rick Moynihan wrote:
Briefly, my main issue with these classes (and I guess other parts of Jini) is that code which uses these classes is hard to unit test because they don't have interfaces.

If the issue is just unit testing, what prevents you from simply writing
your own alternate implementations of the classes and linking them in?

I know the question was for Rick, but nevertheless I like to take the
opportunity to react.

Thanks for this, as your response is largely in line with my views and experience on the matter. I also seem to have neglected to respond to this question.


Around the 'expectation' the contract of some important functionality is
specified as an interface a bunch of tools have been developed, for
example a product such as EasyMock (for more info read
http://today.java.net/pub/a/today/2006/06/20/getting-started-with-easymock-2.html,
haven't used it so don't know whether it is handy or not). Also things
as Google Guice and other DI frameworks most times use in their examples
interfaces instead of classes that can be extended, resulting in a
mindset that interfaces is what people expect for DI (note I'm not
saying this is correct).

I have no experience in using EasyMock or anything along those lines, instead preferring to create my own mock's where possible. And I can't say that the experience of wrestling to make mocks out of the Jini classes was rewarding.

I'm also partial to dependency injection, and find the technique particularly useful, primarily because it helps to support unit testing. Again, I've not been using a special DI framework for this. Instead I have found that Commons Digester can deliver this functionality, and for me works particularly well:

http://jakarta.apache.org/commons/digester/

But my main argument against alternate implementations (by extension
that is), is that you often end up with those nasty constructors that
require proper arguments which you don't have or don't want to provide
or that even might fail at construction time. Together with all the
environmental assumptions that lie in the implementation of the class
you are extending, also you might drag in a lot of code just because of
the implementation.

My experience with Jini and mocking is that it can be done, and I did infact manage to mock out various classes (e.g. the ServiceDiscoveryManager) for my purposes. Here (as Mark suggests) I used extension to create my MockServiceDiscoveryManager class. I then added a few extra methods to allow me to configure different expected/unexpected behaviors into the implementation.

I must admit that It didn't occur to me that I could have just created my own implementation of the class in the SDM namespace and linked it in at runtime. Unfortunately I think this approach is problematic as it is likely that to get a decent test coverage the developer will want to actually provide multiple implementations of the mock, i.e. one that throws RemoteExceptions, one that behaves correctly etc... It seems to me that the right place to determine which class to use is the test, not the build script. Developers may also want their mock SDM to be named in a manner that indicates the mocks behaviour e.g. RemoteExceptionThrowingServiceDiscoveryManager.

Regarding Dependency Injection, you ideally want to remove knowledge of the implementation until runtime. Unfortunately with the Jini classes as they stand this isn't really possible.

Another example I've mentioned before is the partitioning of responsibilities on LookupDiscoveryManager also makes this awkward because their is no interface that unifies *ALL* the responsibilities of the class (other than the class itself).

Interfaces gives an ultimate freedom and allow for minimal dependencies
and I don't see why we can't factor out some of the functionality of SDM
e.g. into an interface, do you Bob?

None of this stuff is particularly hard, and I don't mean to be picky, as there are clearly ways around some of these issues. My problem is only that these things could all be a bit easier. If River is going to break API's for the repackaging to org.apache, why not also clean up these issues through introducing a few interfaces etc?

If these issues can't be resolved, would it be worthwhile creating configurable mock implementations of these Jini classes??

--
Rick Moynihan
Software Engineer
Calico Jack LTD
http://www.calicojack.co.uk/

Reply via email to