开发者

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..*/);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜