The Artima Developer Community
Sponsored Link

Java Buzz Forum
Injecting Dependencies: My Test Classes Want Injection Too

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
dion

Posts: 5028
Nickname: dion
Registered: Feb, 2003

Dion Almaer is the Editor-in-Chief for TheServerSide.com, and is an enterprise Java evangelist
Injecting Dependencies: My Test Classes Want Injection Too Posted: Dec 6, 2004 9:27 AM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by dion.
Original Post: Injecting Dependencies: My Test Classes Want Injection Too
Feed Title: techno.blog(Dion)
Feed URL: http://feeds.feedburner.com/dion
Feed Description: blogging about life the universe and everything tech
Latest Java Buzz Posts
Latest Java Buzz Posts by dion
Latest Posts From techno.blog(Dion)

Advertisement
I like injecting dependencies. It makes my code a lot cleaner and easier to deal with. So, when I find a service locator lookup method such as a Spring getBean("foo), my nose turns up a little. On a current project, I see these getBean() calls in various JUnit tests. The Spring Beans themselves often have a public field called springBeanName, which the test goes too, to look up the right bean. Initial Code This meant that the code looked like this: A Base Test Case class has within it: Code to configure logging Code to setup Spring: String[] paths = {"classpath:applicationContext*.xml"}; ctx = new XmlWebApplicationContext(); ctx.setConfigLocations(paths); ctx.setServletContext(new MockServletContext("")); ctx.refresh(); Some mock objects which various test classes can grab Helper methods to get Spring managed beans. E.g. a DAO: protected UserDAO getUserDao() { return (UserDAO) getBean(UserDAO.springBeanName); } Then a test itself will extend the base class, and either grab a bean from a helper method, or do a getBean() themselves. Injecting into JUnit classes I want to be able to put my set/get injection methods on my test classes, and have Spring do the rest. Luckily, Colin and Dmitriy pointed me to org.springframework.test.AbstractDependencyInjectionSpringContextTests, which likes to hang out in the Spring Mocks package (not core Spring). It simply allows you to bootstrap your test class, and have Spring wire you up nicely. I changed my BaseTestCase to now implement this abstract class, and overrite the method which returns the config locations. Something like: protected String[] getConfigLocations() { return new String[] { "classpath:applicationContext*.xml" }; } Now, in my test cases I setup a get/set combo for the types that I wish to inject. For example: public class AddSiteTest extends BaseTestCase { public void testAddingValidSite() throws Exception { TestCase.assertEquals("AddSiteTest action did not return SUCCESS", Action.SUCCESS, getAction().execute()); } // ------------------------------------------------------------------------ // Spring Dependencies: BaseTestCase will autowire by type // ------------------------------------------------------------------------ private AddSite action; public AddSite getAction() { return action; } public void setAction(AddSite action) { this.action = action; } } What I really want: No auto-wire, let me wire it This has got me pretty much what I wanted. My test classes not have dependencies injected. However, I kinda want one more step. Rather than wiring up automatically by type, I would rather: Create a test-applicationContext.xml which has the wiring of test classes: E.g. <bean id="addSiteTest" class="foo.web.actions.AddSiteTest"> <property name="action"><ref bean="addSiteAction"/></property> </bean> Create one get/setAction in the BaseTestCase: private Action action; public Action getAction() { return action; } public void setAction(Action action) { this.action = action; } With this configuration all of my tests could delve and grab the action via getAction() without having to do anything else. For this to work, I am basically asking Spring for an API like: injectDependencies(Object toInject, Spring beanIdWithWhichToGetDependenciesFrom, ...); E.g. injectDependencies(this, getMyBeanId(), ...); Then in the given class you could override getMyBeanId(), or you could default to "my class name with the first letter lower-cased" for ease of use :) NOTE: You can auto-wire by name: Declare protected variables of the required type which match named beans in the context. This is autowire by name, rather than type. This approach is based on an approach originated by Ara Abrahmian. Setter Dependency Injection is the default: set the populateProtectedVariables property to true in the constructor to switch on Field Injection. Anyway, I am just glad to have Spring watching my back on the testing side too...

Read: Injecting Dependencies: My Test Classes Want Injection Too

Topic: JavaJobs.com Previous Topic   Next Topic Topic: Mini Porting guide of Linux Applications to Windows + NailGun (for faster startup of Java Apps)...

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use