How to use AnnotationConfigWebApplicationContext (Spring framework) to load configuration class during unit test
I use Spring framework 3.0.5 to build a web application. I use @Configuration annotation to configure my domain object, and some of the domain objects are with session scope. And when I write a unit test using jUnit 4.8.2, the AnnotationConfigWebApplicationContext
variable cannot get the beans which are defined in configuration class.
I always get the following exceptions:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'country' is defined
Is there anyone who can give me some advice for this problem? Thanks a lot!
Here is my configuration class, unit test class, DAO class and domain object class. (I use annotation to configure the app instead of xml)
Configuration class:
@Configuration
public class RegionDomainObj
{
/**
* Define City Domain Object bean
*/
@Bean
@Scope("session")
public CityImp city()
{
return new CityImp();
}
/**
* Define City IP Domain Object bean
*/
@Bean
@Scope("session")
public CityIPImp cityIP()
{
return new CityIPImp();
}
/**
* Define Country Domain Object bean
*/
@Bean
@Scope("session")
public CountryImp country()
{
return new CountryImp();
}
/**
* Define Country IP Domain Object bean
*/
@Bean
@Scope("session")
public CountryIPImp countryIP()
{
return new CountryIPImp();
}
/**
* Define Locale Domain Object bean
*/
@Bean
@Scope("session")
public LocaleImp locale()
{
return new LocaleImp();
}
/**
* Define Region Domain Object bean
*/
@Bean
@Scope("session")
public RegionImp region()
{
return new RegionImp();
}
/**
* Define Top Level Domain Domain Object bean
*/
@Bean
@Scope("session")
public TopLevelDomainImp topLevelDomain()
{
return new TopLevelDomainImp();
}
}
Test super class:
@RunWith(SpringJUnit4ClassRunner.class)
public class TestENV
{
protected AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext;
@Before
public void setUp()
{
annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext();
annotationConfigWebApplicationContext.refresh();
}
}
Unit Test class:
public class CountryDAOTest extends TestENV
{
private ICountryDAO countryDAO;
private ICountry country;
@Before
public void setUpLocalTestENV()
{
this.country = (ICountry) this.annotationConfigWebApplicationContext.getBean("country");
this.countryDAO = (ICountryDAO) this.annotationConfigWebApplicationContext.getBean("crazyamsCountryDAO");
}
/* Test save country */
@Test
public void testSaveCountry()
{
this.country.setCode("AU");
this.country.setName("Australia");
this.countryDAO.save(this.country);
/* ignore the assert functions */
}
}
Update
Maybe I make this problem too complex, you know, when we use AnnotationConfigApplicationContext
, we can use the following code to register bean definitions.
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
annotationConfigApplicationContext.register(TestProcessUnitConfig.class, OtherClazz.class);
And in my project, I use Spring MVC with annotation support, and I use AnnotationConfigWebAppli开发者_StackOverflowcationContext
instead of AnnotationConfigApplicationContext
.
Although they are very similar, AnnotationConfigWebApplicationContext
doesn't provide "register" function.
And I just want to know whether there is another way to register bean definition into AnnotationConfigWebApplicationContext
or not.
I think you need to use your @Configuration class in the context constructor:
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(RegionDomainObj.class);
or with register:
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
annotationConfigApplicationContext.register(RegionDomainObj.class);
As far as I know, AnnotationConfigWebApplicationContext
(with the 'Web') is for JSF things.
I don't know if that's the cause but there is one thing that bothers me:
Your exporting country
as an implementation class:
/**
* Define Country Domain Object bean
*/
@Bean @Scope("session") public CountryImp country(){
return new CountryImp();
}
But reference it as an interface:
this.country = (ICountry) this.annotationConfigWebApplicationContext.getBean("country");
The more obvious way would be to export it as interface as well:
/**
* Define Country Domain Object bean
*/
@Bean @Scope("session") public ICountry country(){
return new CountryImp();
}
Try and see if that makes a difference. Even if it doesn't, it improves your code.
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named
This error appears when something wrong with your configuration classes. In your case you have to directly define where you beans defined. So, add next codelines after @Configuration
in your test class:
@WebAppConfiguration
@ContextConfiguration(classes={/*..your configuration classes*/})
@PropertySource(/*.. your possible properties files..*/);
精彩评论