I have made a class called MailMessage, encapsulating the MimeMessage of the javax.mail API. The constructor of MailMessage attempts to retrieve a javax.mail.Session object using a JNDI lookup. When used within the scope of a container, MailMessage is passed a reference to a mail session defined on the server. So far so good.
Now I try to write a unit test class called MailMessageTest. When initializing a new MailMessage (in the setup method), obviously due to the lack of a container environment, no mail session can be found using the lookup. My question: is there any way to make the JNDI lookup return a valid mail session, just for test purposes?
This is a common enough problem with JNDI. Unfortunately, JNDI was not designed in a particularly testable way.
To solve this sort of problem I wrote a simple (and, as it happens, very fast) in-memory JNDI implementation which can be started up in a test case and populated with whatever objects you need. It took me about a week to get it implemented and working properly (some of the semantics of the JNDI calls are a bit strange). To use it, just set the JNDI initialization classname parameter to the name of your IntialContextFactory implementation rather than the one to be used for the live deployment.
You could either have a go at writing one yourself, or find one someone else has written. If you want to read/use mine it's available in my "stringtree" project in the package org.stringtree.jndi. There's just three source files. Presumably some other people have done implementations, too.
Originally posted by Frank Carver: Presumably some other people have done [JNDI] implementations, too.
One such example can be found from the MockEJB project.
Basically, you just need to do "MockContextFactory.setAsInitial();" in your tests' setUp() method and "MockContextFactory.revertSetAsInitial();" in the tearDown(). In between these steps, your tests and code under test are free to do "new InitialContext();" and they get a reference to the MockEJB implementation of the JNDI tree.
So in all cases I�d have to go with a customized/substitute implementation of the JNDI tree. Not sure if I would want to go through the burden of creating or customizing one just for test purposes (btw Frank I believe InMemoryContextFactory still misses a private constructor�hehheh). Also not sure if the mock EJB project is suitable for other resources than EJBs, furthermore the project seems to lack of a ready-to-use code release (jar) without having to implement external releases such as commons logging???
Joined: Jan 07, 1999
btw Frank I believe InMemoryContextFactory still misses a private constructor�hehheh
That's the beauty of open source. You are completely free to add one in your copy.
I still don't think it would improve the code, though.
In general I'm against writing code which is never going to be called. And if someone really wants to construct a new InMemoryContextFactory for some reason, who am I to say they should not?
Joined: Jan 23, 2002
Originally posted by Kjeld Sigtermans: Also not sure if the mock EJB project is suitable for other resources than EJBs
I've used the MockContextFactory from MockEJB several times on projects that had nothing whatsoever to do with EJBs.
Joined: Aug 10, 2006
furthermore the project seems to lack of a ready-to-use code release (jar)
Sorry to have to respond to my own reply but what I said before is wrong. Somehow I overlooked the lib folder with the jar files completely.
Joined: Aug 10, 2006
Ok great: the MockEJB solution works...:
To be able to use MockContextFactory I had to implement mockejb.jar and cglib-full-2.0-RC2.jar which are both in the MockEJB distribution.