About a month ago--I don't remember where--someone provided a JUnit TestCase implementation that loaded a Spring ApplicationContext then set instance variables via java reflection. I liked the concept, but have come up with a couple of refinements of my own. Maybe others will find following implemenation useful.
ContextTestCase will only load the ApplicationContext once, for a test class. If all the test classes in a test suite have same context files then ApplicationContext only loads once for the entire test suite. If the context files change from test class to test class a new ApplicationContext will be loaded/reloaded as needed.
First, create a test class that inherits from ContextTestCase.
To initialize the context call initialize method in setUp():
To get an instance to test call getBean():Code:public void setUp() throws Exception { initialize( "contextFile1.xml,contextFile2.xml" ); }
Hope you find following implementation useful:Code:public void testMethod() throws Exception { final MyClass ref = (MyClass)getBean("myClassBean"); // proceed to test }
Code:import java.util.StringTokenizer; import junit.framework.TestCase; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * A JUnit TestCase extension that simplifies integration testing by making * available a Spring application context. This class short-circuits the * 'set all instance variables null before every test method' mechanism in favor * of loading Spring environment only once before executing any test methods. */ public class ContextTestCase extends TestCase { private static String[] contextFiles = null; private static ApplicationContext context = null; protected final static Object getBean( String bean ) { return context.getBean(bean); } protected final static ApplicationContext getContext() { return context; } /** * Alternate form to initialize/load context * @param xmlFiles in comma delimited string */ protected final synchronized void initialize( String xmlFiles ) throws Exception { String[] contextFiles = toStringArray( xmlFiles ); initialize(contextFiles); } /** * @param xmlFiles context files that specify objects available * in Spring application environment. */ protected final synchronized void initialize( String[] xmlFiles ) throws Exception { if( context == null || !same( xmlFiles, contextFiles ) ) { contextFiles = xmlFiles; context = new ClassPathXmlApplicationContext( xmlFiles ); // load context StringBuffer msg = new StringBuffer("<<< CONTEXT LOADED >>> ["); for( int i = 0; i < xmlFiles.length; i++ ) { if ( i > 0 ) { msg.append(" "); } msg.append( xmlFiles[i] ); } msg.append("] IN class='"); msg.append( this.getClass().getName() ); msg.append("'"); System.out.println( msg.toString() ); } } private boolean same( String[] files1, String[] files2 ) { boolean ret = true; ret = files1 != null && files2 != null && files1.length == files2.length; // true if both not null & same length arrays // loop stops if ret==false for( int i = 0; ret && i < files1.length; i++ ) { ret = files1[i].equals( files2[i] ); } return ret; } private String[] toStringArray( String listing ) { String[] ret = null; StringTokenizer t = new StringTokenizer( listing, "," ); final int count = t.countTokens(); ret = new String[count]; for( int i = 0; i < count; i++ ) { ret[i] = t.nextToken().trim(); } return ret; } }


Reply With Quote