使用SpringJUnit4ClassRunner在测试中加载Spring应用程序上下文失败

4
我无法理解为什么Spring无法在以下定义的测试类中加载应用程序上下文:

我无法理解为什么Spring无法在以下定义的测试类中加载应用程序上下文:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations={"/springMVC-config/mainController-servlet.xml"})
    public class DiagnosticsControllerTest {

    @Mock
    DiagnosticsService diagnosticsService;

    private DiagnosticsController diagnosticsController;

    private MockMvc mockMvc;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        diagnosticsController = new DiagnosticsController();
        diagnosticsController.setService(diagnosticsService);
        this.mockMvc = MockMvcBuilders.standaloneSetup(diagnosticsController).build();
    }

    @Test
    public void shouldRun() {
        assertTrue(1 == 1);
    }
}

'mainController-servlet.xml'文件在"myproject\src\main\webapp\WEB-INF\springMVC-config\mainController-servlet.xml"路径下。

我遇到的错误是:

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:228)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:230)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:249)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    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:193)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [springMVC-config/mainController-servlet.xml]; nested exception is java.io.FileNotFoundException: class path resource [springMVC-config/mainController-servlet.xml] cannot be opened because it does not exist

我尝试将上下文配置的位置更改为以下方式:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/springMVC-config/mainController-servlet.xml")
public class DiagnosticsControllerTest {
...
}
4个回答

2

除了无法引用正确的XML配置文件路径之外,事实上:

您甚至没有在提供的示例中使用Spring TestContext Framework

相反,您只使用了Mockito和Spring MVC Test(即MockMvc)。

因此,您可以完全删除@RunWith@ContextConfiguration声明。


1

这将起作用。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:**/webapp/WEB-INF/springMVC-config/mainController-servlet.xml")
public class DiagnosticsControllerTest {
...
}

1
说服某人将这些配置文件移动到另一个位置将会很困难:@Mihir Gohel,你的解决方案没有起作用。我认为问题出在我有几个XML文件(都在WEB-INF子文件夹中),我有一种印象不是所有文件都被加载了。在调查了漫长的堆栈跟踪后,我发现其他关于某些bean加载错误的错误:Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'XXX_ds' is defined",其中'XXX_ds'是数据源的名称。 - belgoros
@Mihir Gohel:在定义@ContextConfiguration时,至少在IntelliJ中少了一个错误:我可以声明带有@Autowired注释的注释控制器,如下所示:private DiagnosticsController diagnosticsController - belgoros
不,还有其他的bean Spring无法绑定,以及一个找不到数据源的问题。所以最初的错误说ApplicationContext未找到仍然存在。真的很奇怪:(。 - belgoros
你能试试我在代码中所做的修改吗?不确定,但希望它能解决问题。或者你可以分享 Github 仓库链接,我会看一下。 - Mihir Gohel

0

src/main/webapp 不在类路径上,因此找不到文件。

请参见Spring @ContextConfiguration 如何将正确的位置放入xml,了解为什么将Spring配置放入webapp中是不好的。

解决方案是将配置移动到src/main/resources中,并调整加载Spring配置文件的方式以在类路径上查找它们。如果您正在使用web.xml文件,则只需在其前面加上classpath:即可。

还有其他解决方案,但我认为这是长期内最好的选择。


0
为了解决“无法加载应用程序上下文”的错误,我不得不将Spring升级到4.3.6.RELEASE版本,JUnit升级到4.12版本。当我引入lambda表达式后,尝试使用Java 1.8运行JUnit测试时,即使文件位于src/main/resources目录下,也会出现此错误。

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