2013-07-30 49 views
2

春3.2.3.Release和Junit4 4.11Spring MVC的REST控制器測試不會自動裝配的WebApplicationContext

我創建了一個web應用的Spring MVC REST項目。這是具有環繞服務和域實體的控制器的項目。來自另一個項目的DAO和服務都經過了單元測試並且工作正常,所以這不是問題。 DAO和服務來自一個編譯的jar文件。我使用的是maven,所以我確實有Spring-web,Spring-webmvc,Spring Core,Spring-Beans,Spring-test ... Spring-test是3.2.3.Release版本,而不是單獨的GitHub版。

我已經花了2天的時間查看Internet,Google和StackOverflow以及Spring論壇的確切答案,但我無法得到我需要的確切答案,所以我需要另一組眼睛來看看我的文件,看看是否有什麼基本錯誤。

問題是我的單元測試不起作用,它非常小,但是出現了一個巨大的錯誤,我根本無法執行任何測試。因此,讓我開始列出我的代碼和xml文件。

如果任何人都可以查看錯誤並查看代碼,如果有問題,請告訴我。與此同時,我將繼續自己做更多的研究。

我會從控制檯錯誤啓動:因爲在DAO和服務罐子依賴

(main)2013-07-30 13:33:56,336 INFO [org.hibernate.impl.SessionFactoryImpl] - <closing> 
(main)2013-07-30 13:33:56,336 ERROR [org.springframework.test.context.TestContextManager] - <Caught exception while allowing TestExecutionListener [org.springframework.test.context[email protected]] to prepare test instance [[email protected]]> 
(main)java.lang.IllegalStateException: Failed to load ApplicationContext 
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157) 
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:321) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 
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:71) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
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 'invoiceControllerTests': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.context.WebApplicationContext com.tom.rest.controller.invoice.InvoiceControllerTests.wac; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.springframework.web.context.WebApplicationContext] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1120) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461) 
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) 
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) 
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) 
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607) 
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) 
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) 
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:103) 
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1) 
at org.springframework.test.context.support.DelegatingSmartContextLoader.loadContext(DelegatingSmartContextLoader.java:228) 
at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:124) 
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148) 
... 24 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.context.WebApplicationContext com.tom.rest.controller.invoice.InvoiceControllerTests.wac; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.springframework.web.context.WebApplicationContext] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514) 
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) 
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285) 
... 39 more 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.springframework.web.context.WebApplicationContext] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:949) 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:818) 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:730) 
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486) 
... 41 more 

applicationContext.xml中,這些進口都來自於該項目。

<import resource="classpath:project-dao.xml"/> 
<import resource="classpath:project-engines.xml"/> 
<import resource="classpath:project-infrastructure.xml"/> 
<import resource="classpath:project-interface.xml"/> 
<import resource="classpath:project-service.xml"/> 
<import resource="classpath:project-transactions.xml"/> 
<import resource="classpath:project-ui.xml"/> 
<import resource="classpath:project-webservices.xml" /> 

<context:component-scan base-package="com.tom.viper" /> 
<context:annotation-config /> 

<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/> 

<bean id="invoiceControllerTests" class="com.tom.rest.controller.invoice.InvoiceControllerTests" /> 

用SpringMVC-servlet.xml中

<beans> 
    <context:component-scan base-package="com.tom.viper, com.tom.cobra" /> 

<mvc:annotation-driven> 
    <mvc:message-converters register-defaults="true"> 
     <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
      <property name="objectMapper"> 
      <bean class="com.fasterxml.jackson.databind.ObjectMapper"> 

        <property name="dateFormat"> 
         <bean class="java.text.SimpleDateFormat"> 
          <constructor-arg type="java.lang.String" value="yyyy-MM-dd"></constructor-arg> 
         </bean> 
        </property> 
      </bean> 
      </property> 
     </bean> 
    </mvc:message-converters> 
</mvc:annotation-driven> 

<bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
    <property name="supportedMediaTypes" value="application/json"/> 
</bean> 

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> 
    <property name="messageConverters"> 
     <list> 
     <ref bean="jsonHttpMessageConverter" /> 
     </list> 
    </property> 
</bean> 

<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> 
    <property name="messageConverters"> 
     <list> 
     <ref bean="jsonHttpMessageConverter" /> 
     </list> 
    </property> 
</bean> 
</beans> 

的web.xml

<web-app> 
    <context-param> 
    <param-name>log4jConfigLocation</param-name> 
    <param-value>classpath:/log4j.properties</param-value> 
</context-param> 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
    /WEB-INF/classes/applicationContext.xml 
    /WEB-INF/classes/springmvc-servlet.xml 
    classpath:project-dao.xml 
    classpath:project-engines.xml 
    classpath:project-infrastructure.xml 
    classpath:project-interface.xml 
    classpath:project-service.xml 
    classpath:project-transactions.xml 
    classpath:project-ui.xml 
    classpath:project-webservices.xml 
    </param-value> 
</context-param> 

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<!-- Servlets --> 
<servlet> 
    <servlet-name>springmvc</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<servlet> 
    <servlet-name>jUnitHostImpl</servlet-name> 
    <servlet-class>com.google.gwt.junit.server.JUnitHostImpl</servlet-class> 
</servlet> 

<servlet-mapping> 
    <servlet-name>springmvc</servlet-name> 
    <url-pattern>/rest/*</url-pattern> 
</servlet-mapping> 

<servlet-mapping> 
    <servlet-name>jUnitHostImpl</servlet-name> 
    <url-pattern>/RevenueManager/junithost/*</url-pattern> 
</servlet-mapping> 

<!-- Servlets --> 

<!-- Default page to serve --> 
<welcome-file-list> 
    <welcome-file>index.jsp</welcome-file> 
</welcome-file-list> 

</web-app> 

現在控制器測試:

@RunWith(SpringJUnit4ClassRunner.class) 
@WebAppConfiguration 
@ContextConfiguration(locations = 
{ 
"/applicationContext.xml", 
"/springmvc-servlet.xml", 
"classpath:project-infrastructure.xml", 
"classpath:project-dao.xml", 
"classpath:project-service.xml" }) 
public class InvoiceControllerTests 
{ 
@Autowired 
private WebApplicationContext wac; 

private MockMvc mockMvc; 

@Before 
public void setup() 
{ 
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); 
} 

@Test 
public void getInvoices() 
{ 
    assertEquals(true, true); 
} 
} 

回答

0

我來到了一個新的公司,有一個現有的Spring DAO和服務層創建和完整的單元測試。他們使用Ivy來處理依賴和Ant build.xml文件來處理構建。我推測當創建JAR時,這將是一個包含所有配置文件和必要jar文件的自包含文件(封裝)。當我打開JAR文件時,我很驚訝沒有配置文件或jar文件,它只是項目本身的Java代碼。這就是爲什麼沒有Spring配置文件。

在我的新Maven項目中,它要求我填寫前一個項目中缺少的所有jar,所以我只是決定創建一個新的Maven Spring DAO/Service項目並將所有代碼都帶過來。

所以更新:
在這個新的DAO和服務的Maven項目中,我有Spring配置文件; SRC /主/資源/春 當這個新的JAR編譯,新的Spring配置文件在: WEB-INF /班/春

所以,在我的Spring Web MVC框架項目,這裏是我的applicationContext.xml現在:

<import resource="classpath*:projct-dao.xml"/> 
<import resource="classpath*:projct-engines.xml"/> 
<import resource="classpath*:project-infrastructure.xml"/> 
<import resource="classpath*:project-interface.xml"/> 
<import resource="classpath*:projct-service.xml"/> 
<import resource="classpath*:projct-transactions.xml"/> 
<import resource="classpath*:project-ui.xml"/> 
<import resource="classpath*project-webservices.xml" /> 

這裏是處理Spring上下文文件web.xml中的一部分:

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
    /WEB-INF/classes/applicationContext.xml 
    /WEB-INF/viper-servlet.xml 
    classpath*:project-dao.xml 
    classpath*:project-engines.xml 
    classpath*:project-infrastructure.xml 
    classpath*:poject-interface.xml 
    classpath*:project-service.xml 
    classpath*:project-transactions.xml 
    classpath*:projct-ui.xml 
    classpath*:project-webservices.xml 
    </param-value> 
</context-param> 

添加通配符(*)到classpath結束使它尋找失蹤的春天上下文文件。這解決了我的網絡應用程序開始的問題...我希望這可以幫助別人。

0

刪除

<bean id="invoiceControllerTests" class="com.tom.rest.controller.invoice.InvoiceControllerTests" /> 

在您的applicationContext.xml中。

0

您可以使InvoiceControllerTest實現ApplicationContextAware並從生命週期方法的實現中獲取applicationContext的實例。
或者,您可以自動裝配特定的控制器實例ü要測試在烏拉圭回合測試類,做一個獨立的設置,像這樣,
this.mockMvc = MockMvcBuilders.standaloneSetup(this.invoiceController).build();

+0

我明白了......呃,我剛剛發現了問題的真相,我會用我發現的內容更新我的第一個問題。 – tjholmes66

相關問題