Spring @ContextConfiguration如何为xml文件指定正确的位置?

56
在我们的项目中,我们正在编写一项测试来检查控制器是否返回正确的模型视图。
@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{
....

这份文档不够清晰易懂

如何确保 contextannotation 加载正确的 xml?

编辑 v2

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

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

并且将web.xml更改为webinf中的

<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)
9个回答

77

我们的测试看起来像这样(使用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”的方法正确吗? - Andry

43

这就是为什么不要把配置文件放在 webapp 文件夹中的原因。

据我所知,从单元测试中访问 webapp 文件夹中的文件没有好的方法。相反,您可以将配置文件放在 src/main/resources 中,这样可以从单元测试中访问它(如文档中所述),同时也可以通过在 contextConfigLocation 中使用 classpath: 前缀来从 web 应用程序中访问它。

另请参阅:


1
你有关于“classpath:”的文档参考吗? - David
@Dvd:我猜你需要 classpath:be/..一堆文件夹../configuration/root-context.xmlclasspath:be/..一堆文件夹../configuration/applicationContext-security.xml - axtavt

22

我认为这是一个与Maven相关的问题。 Maven不会将文件从/src/main/resources复制到target-test文件夹中,如果你一定要这样做,那么你需要通过配置资源插件来手动完成。

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

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

/src/main/resources 不应该被复制到 target/test-classes。测试类 - dan carter
4
/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 carter
@Dan:我认为,如果您可以在“测试”上下文中重用(部分)来自“主要”配置的内容,则让Maven使用maven-resources-plugin复制现有文件以进行测试是有意义的。因此,说“不应该”被复制有点太严厉了。当然,Maven默认情况下不会这样做,但是如果您有充分的理由自己这样做...为什么不呢? - fasseg
@fasseg:@Dan 的意思是你不需要将 main 中的配置复制到 test 上下文中,因为这个配置已经提供给了单元测试(因为在运行它们时,target/classes 已经放置在类路径上)。 - ahmehri

11

简单的解决方案是

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

来自spring论坛


6
我们使用的技术包括:
@ContextConfiguration(locations="file:WebContent/WEB-INF/spitterMVC-servlet.xml")

这个项目是一个Eclipse动态Web项目,那么路径就是:

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

4

从以下位置加载文件:{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..          
    }
}

4
假设您要创建一个与app-context.xml无关的测试上下文test-context.xml,用于测试,请将test-context.xml放在/src/test/resources下。 在测试类中,在类定义的顶部添加@ContextConfiguration注释。
@ContextConfiguration(locations = "/test-context.xml")
public class MyTests {
    ...
}

Spring文档上下文管理


0

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = {"/Beans.xml"}) public class DemoTest{}

在这段代码中,我们使用了Spring框架提供的SpringJUnit4ClassRunner类来运行DemoTest测试类,并通过@ContextConfiguration注解指定了Beans.xml文件的位置。


-2
有时候,这可能只是一些简单的问题,比如由于某些清理操作而在测试类文件夹中缺少资源文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接