JUnit的@ContextConfiguration(来自/ webapp的配置)

时间:2017-03-09 22:12:44

标签: java spring junit

美好的一天。

为我的Spring应用程序编写JUnit测试可以解决下一个问题。 我的标准上下文配置文件存储在/ webapp中的项目中(不是单元测试的类路径的一部分)。

项目结构: project structure

JUnit测试:

    @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/config/application-context.xml", "file:src/main/webapp/WEB-INF/config/mvc-config.xml"})
public class AdvertORMServiceTest {

    @Autowired
    private AdvertORMService jpaAdvertORMService;

    @Test
    public void queryAllAdvertsTest() {
        List<Advert> adverts = jpaAdvertORMService.findAll();
        Assert.assertNotNull(adverts);
    }

}

应用context.xml中:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">


    <context:property-placeholder location="classpath:util.properties" />
    <!--Activates various annotations to be detected in bean classes: Spring's @Required and @Autowired and so on-->
    <context:annotation-config/>

    <!-- Datasource.  -  MySQL -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClass}"/>
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}" />
    </bean>

    <!--Do not forget activate @Transactional JPA annotation with <annotation-driven/>-->
    <!-- JPA Persistence Context and EntityManager configuration -->
    <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
        <!--packagesToScan - search Entity and mapping them -->
        <property name="packagesToScan" value="by.GetItFree" />
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" >
                <property name="generateDdl" value="true" />
                <property name="showSql" value="true" />
            </bean>
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">false</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <!--it's anti pattern need to delete it, and solv exception:-->
                <!--failed to lazily initialize a collection of role could not initialize proxy - no Session-->
                <!--<prop key="hibernate.enable_lazy_load_no_trans">true</prop>-->
            </props>
        </property>
    </bean>

    <!-- Automatic Transaction Participation-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <jpa:repositories base-package="by.GetItFree.orm.repository" entity-manager-factory-ref="entityManagerFactory"
                      transaction-manager-ref="transactionManager"/>


    <!-- REST template configuration -->
    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/>

</beans>

**mvc-config.xml:**



   <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- context:component-scan This tag will scan @Component, @Repository, @Service, @Controller
         and also resolves @Autowired and @Qualifier -->
    <context:component-scan base-package="by.GetItFree"/>

    <!--
        mvc:annotation-driven configures Spring MVC annotations
        Support for validating @Controller inputs with @Valid, if a JSR-303 Provider is present on the classpath.
        HttpMessageConverter support for @RequestBody method parameters and @ResponseBody method return values
        from @RequestMapping or @ExceptionHandler methods.
     -->
    <mvc:annotation-driven/>

    <!-- activate @Transactional JPA annotation -->
    <tx:annotation-driven/>

    <!-- ViewResolver bean config for mapping strings to jsp views -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- Example: a logical view name of 'showMessage' is mapped to '/WEB-INF/jsp/showMessage.jsp' -->
        <property name="order" value="1"/>
        <property name="prefix" value="/WEB-INF/view"/>
        <property name="suffix" value=".jsp"/>
    </bean>


    <mvc:view-controller path="/about.html" view-name="/about/about"/>
    <mvc:view-controller path="/index.html" view-name="/index"/>

    <mvc:view-controller path="/" view-name="/index"/>


    <!-- Static Resources Configuration (get access to static sources such as CSS and JavaScript files) -->
    <mvc:resources mapping="/resources/**" location="/resources/"/>

    <mvc:interceptors>

        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
                <property name="paramName" value="languageVar"/>
            </bean>
        </mvc:interceptor>
    </mvc:interceptors>

    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="ru"/>
        <!-- cookieMaxAge in seconds. if you set it to -1, the cookie will be deleted when browser is closed) -->
        <property name="cookieMaxAge" value="100000"/>
    </bean>

    <!-- MessageSource ReloadableResourceBundleMessageSource configuration -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames" value="classpath:/locales/messages,classpath:util"/>
        <property name="cacheSeconds" value="1"/>
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>

    <!--
     mvc:annotation-driven configures Spring MVC annotations
     Support for validating @Controller inputs with @Valid, if a JSR-303 Provider is present on the classpath.
     HttpMessageConverter support for @RequestBody method parameters and @ResponseBody method return values
     from @RequestMapping or @ExceptionHandler methods.
    -->
    <mvc:annotation-driven>
        <!--use int RestController to produce pretty json response-->
        <mvc:message-converters>
            <bean id="jacksonHttpMessageConverter"
                  class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="prettyPrint" value="true"/>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
</beans>

堆栈跟踪:

    java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    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:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0': Invocation of init method failed; nested exception is java.lang.IllegalStateException: WebApplicationObjectSupport instance [ResourceHttpRequestHandler [locations=[class path resource [resources/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@12ad1b2a]]] does not run in a WebApplicationContext but in: org.springframework.context.support.GenericApplicationContext@536aaa8d: startup date [Fri Mar 10 00:42:32 MSK 2017]; root of context hierarchy
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:108)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:251)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
    ... 31 more
Caused by: java.lang.IllegalStateException: WebApplicationObjectSupport instance [ResourceHttpRequestHandler [locations=[class path resource [resources/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@12ad1b2a]]] does not run in a WebApplicationContext but in: org.springframework.context.support.GenericApplicationContext@536aaa8d: startup date [Fri Mar 10 00:42:32 MSK 2017]; root of context hierarchy
    at org.springframework.web.context.support.WebApplicationObjectSupport.getWebApplicationContext(WebApplicationObjectSupport.java:112)
    at org.springframework.web.context.support.WebApplicationObjectSupport.getServletContext(WebApplicationObjectSupport.java:128)
    at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.initContentNegotiationStrategy(ResourceHttpRequestHandler.java:306)
    at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.afterPropertiesSet(ResourceHttpRequestHandler.java:268)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
    ... 46 more
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 5.006 sec <<< FAILURE!

感谢您的关注。

github链接到项目:project on github

1 个答案:

答案 0 :(得分:2)

看起来应用程序上下文已正确加载,但您必须指示测试类使用Web配置:

@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
        locations = {"file:src/main/webapp/WEB-INF/config/mvc-config.xml", 
                "file:src/main/webapp/WEB-INF/config/application-context.xml"})
public class AdvertORMServiceTest {