How to use different application context for JUnit versus regular execution

Jeth01
Jeth01 used Ask the Experts™
on
Hi,

I have some mock DAOs that I created for some JUnits. I have them autowired with a separate application context file. (They are in a different package and I'm using the component scan) They just return dummy objects instead of fetching from the database. The regular DAOs are through hibernate.
My problem is, I can't figure out how to tell Spring to use that file when running JUnits, and to use the regular XML file otherwise. I want the JUnits to run with the mock DAOs, so we don't need a DB for those. But then when running the application normally, use the real DAOs.
I am fairly new to Spring so this is all a learning experience for me. Any help would be appreciated. Thanks.
One other thing -- I have them in a separate file because they are the same names as the regular DAOs, so that nothing else has to change. But if there is a way to tell Spring to only load the mock ones, or to only use the mock ones for JUnit, then I don't need the separate file.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
A feasible option would be to create a factory class that gives you the application context based on do you want it for JUnit or prod. The factory will load the appropriate conf file and return you the application context loaded with the correct XML beans.

E.g.

public ApplicationContext getApplicationContext(String usage){
    ApplicationContext  context = null;
    if("JUnit".equalsIgnoreCase(usage){
                    context = <load from mock DAO context file>
    }else{
                 context = <load from DB DAO context file>
    }
return context;
}

Author

Commented:
Ok, I thought about that. But where would I put it? We just have our Spring Dispatcher Servlet defined in the web.xml, so then that picks up the application context.  Could I just overwrite the one that is loaded after the fact? We are using GWT, so I'm not sure where to put that. I guess in onModuleLoad()? Would that work?
Thanks!
Hmm..I am assuming that you are using the "org.springframework.web.context.ContextLoaderListener" class to load the context, is that true?

If that is the case, you can add multiple context xmls to the listeners; the later bean definitions will override beans defined with the same id earlier.

So assuming you have your DB DAOs in WEB-INF/applicationContext1.xml and mock DAO's in WEB-INF/applicationContext2.xml; then create 2 separate web.xml or have one entry commented while putting to production. Alternately, if you have a build script(say ant), then you can create 2 separate targets for building the app for JUnit/Db and call the target accordingly which would pick up the relevant web.xml.




<!-- Context Configuration locations for Spring XML files in case of JUnit. Should be commented when using in Prod-->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>WEB-INF/applicationContext1.xml, WEB-INF/applicationContext2.xml</param-value>
	</context-param>

<!-- Context Configuration locations for Spring XML files in case of Prod, should be commented in case of JUnit-->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>WEB-INF/applicationContext1.xml</param-value>
	</context-param>

Open in new window

CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

You can have 3 kind of configuration in Spring 3

1. xml
2. Annotation
3. Java Config

You can mix them too.

A good practice will be to keep test configuration and production configuration separately. In production you can use one configuration, For testing use stubs.

Remember Spring enforces programming to interfaces. That means You can have actual implementation classes for production config file and stub implementations for testing.

So during testing, Instantiate application context using test-appcontext.xml and then do your unit testing.

For example

// In the test environment
ApplicationContext context =
new ClassPathXmlApplicationContext(
“application-config.xml”, “test-infrastructure-config.xml” );

Open in new window


// In the production Oracle environment
ApplicationContext context =
new ClassPathXmlApplicationContext(
“application-config.xml”, “oracle-infrastructure-config.xml”);

Open in new window



For doing integration test , Spring provides a custom JUnit runner called SpringJUnit4ClassRunner.

This will create a proxy for your testcase and you can enjoy all those cool out of the box support that Spring provides in you TestCase

Typical example could be

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:system-test-config.xml”)
public final class AuthenticatorTests {
@Autowired
private TransferService transferService ;
@Test
public void successfulTransfer() {
...
}
@Test
public void failureTransfer() {
...
}
}

Open in new window


--
Thanks
Subin Sugunan
http://www.subinsugunan.com/
More spring posts
If this doesn't work

 ClassPathXmlApplicationContext(
“application-config.xml”, “test-infrastructure-config.xml” );

Open in new window


use String[]

 ClassPathXmlApplicationContext(new String[] {
“application-config.xml”, “test-infrastructure-config.xml” });

Open in new window



--
Thanks
Subin Sugunan
http://www.subinsugunan.com/
More spring posts
Kevin CrossChief Technology Officer
Most Valuable Expert 2011

Commented:
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial