Mocking JNDI
Pubblicato da Luigi il 27 Marzo 2009 in JavaTesting components that use JNDI to get DataSources and other resources can be annoying, because (hopefully) you don't want to run your unit tests inside the application server. JNDI is a good example of how the ServiceLocator makes testing harder.
When you can't turn around the JNDI to get your resources and inject them into your objects... it may be the case of mocking the JNDI system with something that you can control from your tests.
The File System Service Provider could be a replacement for the real JNDI system, with one that you can control easier and have it running outside the the application server.
But, another option is to mock a minimum set of the JNDI system with an in-memory implementation. This is what I did.
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
public class InitialContextFactoryForTest implements InitialContextFactory {
private static Context context;
static {
try {
context = new InitialContext(true) {
Map<String, Object> bindings = new HashMap<String, Object>();
@Override
public void bind(String name, Object obj)
throws NamingException {
bindings.put(name, obj);
}
@Override
public Object lookup(String name) throws NamingException {
return bindings.get(name);
}
};
} catch (NamingException e) { // can't happen.
throw new RuntimeException(e);
}
}
public Context getInitialContext(Hashtable<?, ?> environment)
throws NamingException {
return context;
}
public static void bind(String name, Object obj) {
try {
context.bind(name, obj);
} catch (NamingException e) { // can't happen.
throw new RuntimeException(e);
}
}
}
And this is an example of usage in a unit test:
import javax.naming.Context;
import javax.naming.InitialContext;
import static javax.rmi.PortableRemoteObject.narrow;
import javax.sql.DataSource;
import junit.framework.TestCase;
import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;
public class TestInitialContext extends TestCase {
private DataSource dataSource;
@Override
protected void setUp() throws Exception {
// sets up the InitialContextFactoryForTest as default factory.
System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
InitialContextFactoryForTest.class.getName());
// binds the object
dataSource = getDataSource();
InitialContextFactoryForTest.bind("jdbc/mysql", dataSource);
}
public void testInitialContext() throws Exception {
Context ctx = new InitialContext();
Object ref = ctx.lookup("jdbc/mysql");
DataSource result = (DataSource) narrow(ref, DataSource.class);
assertSame(dataSource, result);
}
private DataSource getDataSource() {
MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource();
dataSource.setUser("username");
dataSource.setPassword("password");
dataSource.setServerName("server");
dataSource.setPort(3306);
dataSource.setDatabaseName("database");
return dataSource;
}
}
The InitialContextFactoryForTest.bind() method is used in the setUp() of the TestCase to bind object that will be needed by the tests, and then your code can use JNDI lookup as usual to get the resources they need.
InitialContextFactoryForTest is a very limited implementation, but it's usually enough to support most common usages of JNDI. Sometime it may be the case to extend it to support more functionalities.
Looking this post, now, I just realized that it may be the case to provide a cleanup() method on InitialContextFactoryForTest to remove all bindings (just cleaning the internal HashMap). So that the the test cases can cleanup the JNDI bindings after a test run, in tearDown() method.
But this sample is just to give an easy hint on how to workaround the JNDI when you can't keep it out from your tests.
Errata corrige: in this article I've made a little confusion on testing terms (mocks, with fake implementation). See Mocks Aren't Stubs. By the way, titling this post "Facking JNDI" would sound funny; this time I prefer keeping a certain degree of approximation over a funny accuracy.
Un Commento a “Mocking JNDI”
Lascia un Commento
Cerca
Calendario
| L | M | M | G | V | S | D |
|---|---|---|---|---|---|---|
| « Feb | Apr » | |||||
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 | 31 | |||||
Archivi
- Gennaio 2010 (2)
- Dicembre 2009 (1)
- Novembre 2009 (3)
- Settembre 2009 (2)
- Agosto 2009 (4)
- Luglio 2009 (1)
- Giugno 2009 (2)
- Maggio 2009 (4)
- Aprile 2009 (2)
- Marzo 2009 (7)
- Febbraio 2009 (5)
- Gennaio 2009 (2)
- Dicembre 2008 (1)
- Novembre 2008 (8)
- Ottobre 2008 (12)
- Settembre 2008 (3)
- Agosto 2008 (2)
- Luglio 2008 (6)
- Giugno 2008 (16)
- Maggio 2008 (2)
- Aprile 2008 (3)
- Marzo 2008 (6)
- Ottobre 2007 (1)
- Settembre 2007 (1)
- Agosto 2007 (5)
- Luglio 2007 (6)
- Giugno 2007 (6)
- Maggio 2007 (1)
- Marzo 2007 (1)
- Febbraio 2007 (2)
- Gennaio 2007 (1)
- Dicembre 2006 (2)
- Novembre 2006 (4)
- Ottobre 2006 (7)
- Settembre 2006 (1)
- Agosto 2006 (2)
- Luglio 2006 (6)
- Giugno 2006 (3)
- Febbraio 2006 (1)
- Gennaio 2006 (1)
- Dicembre 2005 (5)
- Novembre 2005 (2)
- Ottobre 2005 (2)
- Settembre 2005 (7)
- Agosto 2005 (2)
- Luglio 2005 (8)
- Giugno 2005 (12)
Categorie
- Books (7)
- Eclipse (10)
- Errors (2)
- Firefox (7)
- Hardware (14)
- Horror Code (8)
- Internet (17)
- Java (85)
- JavaScript (8)
- Life, universe and everything (29)
- Linux (44)
- Mac (18)
- Software (25)
- Speeches and Conferences (8)
- Web (19)
- Windows (16)
Ultimi Post
- Syntactic sugar and Java arrays.
- 3G USB Stick on Ubuntu
- Ipod touch with Linux
- Karmic and Luks: USB drive encryption made (almost) easy
- Suspend/Resume in Karmic /2
- Suspend/Resume problem in Ubuntu Karmic 9.10 running on MacBook Pro 5.1
- MacBook International Keyboard and Linux
- Mighty Mouse: reverse horizontal scrolling workaround on Ubuntu Linux 9.04
- Skype 2.1.0.47 beta released, and amd64 packages available!
- Linux RAM Disks
My open source projects
Blog License
Blogs I like
Friends' Blogs
- Antonio Terreno & Valter Bernardini
- Bruno Bossola
- Daniele Galluccio
- Domenico Ventura
- Ed Schepis
- Fabrizio Gianneschi
- Filippo Diotalevi
- JavaJournal.it Blog
- Luca Grulla
- Luigi Zanderighi
- Marcello Teodori
- Mida Boghetich
- Muralidharan Chandrasekaran
- Piero Ricca
- Renzo Borgatti
- Simone Bordet
- Uberto Barbini
- Valvolog
- Webtide blogs (Greg Wilkins & Jan Bartel)
Links








can you adapt this example to retrieve MQ from jndi please?
thanks