Spring @ContextConfiguration 如何为xml放置正确的位置

Posted

技术标签:

【中文标题】Spring @ContextConfiguration 如何为xml放置正确的位置【英文标题】:Spring @ContextConfiguration how to put the right location for the xml 【发布时间】:2011-05-21 15:11:13 【问题描述】:

在我们的项目中,我们正在编写一个测试来检查控制器是否返回正确的模型视图

@Test
    public void controllerReturnsModelToOverzichtpage()
    
        ModelAndView modelView = new ModelAndView();
        KlasoverzichtController controller = new KlasoverzichtController();
        modelView = controller.showOverzicht();

        assertEquals("Klasoverzichtcontroller returns the wrong view ", modelView.getViewName(), "overzicht");
    

这将返回异常 null。

我们现在正在配置@contextconfiguration,但我们不知道如何加载位于 src\main\webapp\root\WEB-INF\root-context.xml 的正确 xml

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class TestOverzichtSenario
....

This documentation isn't clear enough to understand

关于如何确保 contextannotation 加载正确的 xml 有什么建议吗?

编辑 v2

我将配置 .xml 文件从 webINF 文件夹复制到

src\main\resources\be\..a bunch of folders..\configuration\*.xml 

并将webinf中的web.xml改为

<param-name>contextConfigLocation</param-name>
<param-value>
            classpath*:configuration/root-context.xml
            classpath*:configuration/applicationContext-security.xml
        </param-value>

现在得到错误

org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/mvc-dispatcher-servlet.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/mvc-dispatcher-servlet.xml]
    org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:341)
    org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
    org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
    org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
    org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
    org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:124)
    org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:93)
    org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)
    org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:467)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:397)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:442)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:458)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:339)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:306)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
    javax.servlet.GenericServlet.init(GenericServlet.java:212)
    com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:80)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:379)
    java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.lang.Thread.run(Unknown Source)

【问题讨论】:

【参考方案1】:

我们的测试如下所示(使用 Maven 和 Spring 3.1):

@ContextConfiguration
(
  
   "classpath:beans.xml",
   "file:src/main/webapp/WEB-INF/spring/applicationContext.xml",
   "file:src/main/webapp/WEB-INF/spring/dispatcher-data-servlet.xml",
   "file:src/main/webapp/WEB-INF/spring/dispatcher-servlet.xml"
  
)
@RunWith(SpringJUnit4ClassRunner.class)
public class CCustomerCtrlTest

  @Resource private ApplicationContext m_oApplicationContext;
  @Autowired private RequestMappingHandlerAdapter m_oHandlerAdapter;
  @Autowired private RequestMappingHandlerMapping m_oHandlerMapping;
  private MockHttpServletRequest m_oRequest;
  private MockHttpServletResponse m_oResp;
  private CCustomerCtrl m_oCtrl;

// more code ....

【讨论】:

非常感谢,它解决了我的问题!但是您认为这种方法:“file:path”是否正确?【参考方案2】:

这就是不将配置放入webapp的原因。

据我所知,没有很好的方法可以从单元测试中访问 webapp 文件夹中的文件。您可以改为将配置放入 src/main/resources,以便您可以从单元测试(如文档中所述)以及 web 应用程序(在 contextConfigLocation 中使用 classpath: 前缀)访问它。

另请参阅:

4.7 Application contexts and Resource paths

【讨论】:

您是否有任何文档参考了“classpath:”的作用? @Dvd: 我猜你需要classpath:be/..a bunch of folders../configuration/root-context.xmlclasspath:be/..a bunch of folders../configuration/applicationContext-security.xml【参考方案3】:

我认为这是一个 Maven 特定的问题。 Maven 不会将文件从 /src/main/resources 复制到 target-test 文件夹。如果您绝对想这样做,您必须自己通过配置资源插件来执行此操作。

更简单的方法是将测试特定的上下文定义放在​​/src/test/resources 目录中并通过以下方式加载:

@ContextConfiguration(locations =  "classpath:mycontext.xml" )

【讨论】:

/src/main/resources 不应复制到目标/测试类。测试类 /src/main/resources 应该被复制到 target/test-classes 文件夹。 test-classes 用于测试资源,即 src/test/java 和 src/test/resources。 src/main/resources 被复制到 target/classes 并且 target/classes 在运行测试时被放置在类路径中,因此 src/main/resources 中的任何 spring 上下文文件都可以作为类路径资源加载到单元测试中,例如src/main/resources/spring/my-context.xml 可以加载为@ContextConfiguration("/spring/my-context.xml") @Dan:我想说,如果可以的话,例如在test 上下文中重用(部分)来自main 的配置,让maven 使用maven-resources-plugin 复制现有文件以进行测试是有意义的。所以说“应该”被复制有点太苛刻了。当然 Maven 默认不这样做,但如果你有充分的理由自己这样做......为什么不呢? @fasseg:@Dan 的意思是你不需要将配置从main 复制到test 上下文,因为这个配置已经提供给单元测试(因为@ 987654328@ 在运行时被放置在类路径中)。【参考方案4】:

简单的解决方案是

@ContextConfiguration(locations =  "file:src/main/webapp/WEB-INF/applicationContext.xml" )

来自spring forum

【讨论】:

【参考方案5】:

我们使用:

@ContextConfiguration(locations="file:WebContent/WEB-INF/spitterMVC-servlet.xml")

项目为eclipse动态web项目,则路径为:

project name/WebContent/WEB-INF/spitterMVC-servlet.xml

【讨论】:

【参考方案6】:

假设您要创建一个独立于 app-context.xml 的 test-context.xml 用于测试,请将 test-context.xml 放在 /src/test/resources 下。在测试类中,在类定义的顶部添加@ContextConfiguration 注解。

@ContextConfiguration(locations = "/test-context.xml")
public class MyTests 
    ...

Spring文档Context management

【讨论】:

【参考方案7】:

project/src/main/webapp/WEB-INF/spring-dispatcher-servlet.xml加载文件

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =  "file:src/main/webapp/WEB-INF/spring-dispatcher-servlet.xml" )     
@WebAppConfiguration
public class TestClass 
    @Test
    public void test() 
         // test definition here..          
    

【讨论】:

【参考方案8】:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "/Beans.xml") 公共类 DemoTest

【讨论】:

【参考方案9】:

有时它可能很简单,例如由于一些清理工作而丢失了 test-classses 文件夹中的资源文件。

【讨论】:

以上是关于Spring @ContextConfiguration 如何为xml放置正确的位置的主要内容,如果未能解决你的问题,请参考以下文章

你了解Spring从Spring3到Spring5的变迁吗?

Spring全家桶笔记:Spring+Spring Boot+Spring Cloud+Spring MVC

学习笔记——Spring简介;Spring搭建步骤;Spring的特性;Spring中getBean三种方式;Spring中的标签

Spring--Spring入门

Spring框架--Spring事务管理和Spring事务传播行为

Spring框架--Spring事务管理和Spring事务传播行为