Java – Why can’t I test the project using JUnit 4

javajunitspringtesting

I am using Spring 3, Hibernate 3 in my project. But I can not test it using JUnit 4.

Here is my Test class:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:WebRoot/WEB-INF/applicationContext.xml"})
public class UserDaoTestCase extends AbstractJUnit4SpringContextTests {

    @Autowired
    private UserDao userDao;

    @Test
    public void testSimple() {
        // do some tests...
    }



    // setters and getters
    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

}

I run this test, and I always get this exception:

java.lang.IllegalStateException: Failed to load ApplicationContext at
org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308)
at
org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at
org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at
org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:333)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:220) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:301)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:303)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at
org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'sessionFactory' defined in URL
[file:WebRoot/WEB-INF/applicationContext.xml]: Invocation of init
method failed; nested exception is org.hibernate.HibernateException:
Unable to get the default Bean Validation factory at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1412)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:557)
at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at
org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:84)
at
org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
at
org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280)
at
org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304)
… 24 more Caused by: org.hibernate.HibernateException: Unable to
get the default Bean Validation factory at
org.hibernate.cfg.beanvalidation.BeanValidationActivator.applyDDL(BeanValidationActivator.java:127)
at
org.hibernate.cfg.Configuration.applyBeanValidationConstraintsOnDDL(Configuration.java:1704)
at
org.hibernate.cfg.Configuration.applyConstraintsToDDL(Configuration.java:1654)
at
org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1445)
at
org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1375)
at
org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:717)
at
org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1469)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1409)
… 37 more Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597) at
org.hibernate.cfg.beanvalidation.BeanValidationActivator.applyDDL(BeanValidationActivator.java:118)
… 45 more Caused by: org.hibernate.HibernateException: Unable to
build the default ValidatorFactory at
org.hibernate.cfg.beanvalidation.TypeSafeActivator.getValidatorFactory(TypeSafeActivator.java:383)
at
org.hibernate.cfg.beanvalidation.TypeSafeActivator.applyDDL(TypeSafeActivator.java:109)
… 50 more Caused by: javax.validation.ValidationException: Unable
to instantiate Configuration. at
javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:272)
at
javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:111)
at
org.hibernate.cfg.beanvalidation.TypeSafeActivator.getValidatorFactory(TypeSafeActivator.java:380)
… 51 more Caused by: java.lang.NullPointerException at
java.util.ResourceBundle.getBundle(ResourceBundle.java:960) at
org.hibernate.validator.engine.ResourceBundleMessageInterpolator.loadBundle(ResourceBundleMessageInterpolator.java:202)
at
org.hibernate.validator.engine.ResourceBundleMessageInterpolator.getFileBasedResourceBundle(ResourceBundleMessageInterpolator.java:182)
at
org.hibernate.validator.engine.ResourceBundleMessageInterpolator.(ResourceBundleMessageInterpolator.java:81)
at
org.hibernate.validator.engine.ResourceBundleMessageInterpolator.(ResourceBundleMessageInterpolator.java:73)
at
org.hibernate.validator.engine.ConfigurationImpl.(ConfigurationImpl.java:57)
at
org.hibernate.validator.HibernateValidator.createGenericConfiguration(HibernateValidator.java:43)
at
javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:269)
… 53 more

My IDE is MyEclipse 9, and I am using JavaEE 6 libraries.

I think my applicationContext.xml is fine, 'cuz it works fine when I run this project in tomcat, no exceptions.

Here is my SessionFactory bean in applicationContext.xml:

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="c3p0DataSource" />
    <property name="packagesToScan">
        <list>
            <value>com.myproject.entity</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
             <prop key="hibernate.connection.provider_class">
                 org.hibernate.connection.C3P0ConnectionProvider
              </prop>
              <prop key="hibernate.hbm2ddl.auto">update</prop>
              <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
              <prop key="hibernate.show_sql">true</prop>
              <prop key="hibernate.format_sql">true</prop>
       </props> 
    </property>
</bean>

How can I do tests using JUnit 4 correctly?

Best Answer

I expect you've got the path to the application-context.xml wrong, as Spring sees it. I'd first try dropping off WebRoot/.

I'd attach the Spring sources to my project and hook-up a debugger, breaking on line:

org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308)

In there, you'll see where it's loading the application context and you can use an interactive expression executer to try multiple different strings to figure out what it can and can't see.

I'd also try this:

@ContextConfiguration(locations = { "classpath*:applicationContext*.xml" })

That work's in my project where the files are in WEB-INF/classes in the deployment.