Question

I'm learning Spring and looking at using Spring Test for my web app (JQuery/CXF/Hibernate). I have been using annotations to wire up my beans and noticed that this sometimes got into the way of polymorphism. For example I have a GenericDAO extended by all DAOs. It is also a concrete class used by simple services, so when I wired it for one of those services, ALL other DAOs became candidates for runtime wiring (because of polymorphism). I could solve that by wiring explicitly by type: @Resource(type= GenericDaoImpl.class), but this goes against the best practice of coding to interfaces ..

Now I want to create unit tests using a MockGenericDaoImpl, and integration tests using GenericDaoImpl. How will I override the annotations? I'm guessing the best approach is to stick to XML-based wiring, so that I can have several versions of beans.xml, one for prod, one for unit tests, one for integration tests, and possibly split them into parallel sub-files, as needed. Isn't this approach more flexible than depending on annotations that either scan to guess the appropriate candidate, or constrain polymorphism? Can someone give me broad directions on how to organize my test configuration setup? Thank you!

Was it helpful?

Solution

How about using @Configuration class? If you're not familiar with this method - you can declare a class that replaces the XML context file and looks something like this:

@Configuration
@ComponentScan({ "com.project.dao"})
public class TestConfiguration {

    @Bean
    public GenericDao getGenericDao() {
         return new MockGenericDaoImpl();
    }
}

In the @ComponentScan annotation just put the relevant packages to scan. This way you're very flexible with the beans you're creating and the way to create them. You can injects mock to the beans whatever way you'd like. Also you can create several test configurations, each configuration for a different purpose. In order to load the context you need to put this annotation on your test class:

@ContextConfiguration(classes={TestConfiguration .class})

OTHER TIPS

Using XML configuration files prevent you from depending on Spring dependencies. You can replace it with another DI framework(maybe Guice, but this is not realistic for big projects I know). Using XML configuration files enables you to code cleanly.

I hate XML but I hate existence of not-business-logic-specific things in my code more. I see you know how to overcome the test issues using XML configuration files. I will try to show how to overcome duplication of implementations(one real one mock implementation) problems using annotations.

You can define your beans via annotations. You can select implementation using aliases:

project.dev.properties:

my.project.dao.xDao=xDaoJpaBean

project.test.properties:

my.project.dao.xDao=xDaoMockBean

<alias name="${my.project.dao.xDao}" alias="xDao"/>

@Autowired
@Qualifier("xDao")
protected XDao xDao;

So you can select your implementation just using your properties file. If you want to use Annotations purely you can do this as well:

@Autowired
@Qualifier("${my.project.dao.xDao}")
protected XDao xDao;

Your build environment will specify which properties file to load, in return your bean will be assigned.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top