4

I can't figure out why Spring can't load the application context in a test class defined as follows:

    @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);
    }
}

The file 'mainController-servlet.xml' is in "myproject\src\main\webapp\WEB-INF\springMVC-config\mainController-servlet.xml"

The error I get is:

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

I tried to change the locations for the context configuration as follows:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/springMVC-config/mainController-servlet.xml")
public class DiagnosticsControllerTest {
...
}
Sam Brannen
  • 29,611
  • 5
  • 104
  • 136
belgoros
  • 3,590
  • 7
  • 38
  • 76

4 Answers4

2

Aside from not being able to reference the correct path to your XML configuration file, the truth is:

You are not even using the Spring TestContext Framework in the example you provided.

Rather, you are only using Mockito and Spring MVC Test (i.e., MockMvc).

Thus, you can simply delete the @RunWith and @ContextConfiguration declarations completely.

Sam Brannen
  • 29,611
  • 5
  • 104
  • 136
1

This will work.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:**/webapp/WEB-INF/springMVC-config/mainController-servlet.xml")
public class DiagnosticsControllerTest {
...
}
Mihir Gohel
  • 316
  • 2
  • 6
  • 1
    Convince someone to move these config files to another location will be difficult : @Mihir Gohel, your solution didn't work. I think the problem comes from the point that I have several XML files (all in WEB-INF sub-folders) ad I have an impression that not all are loaded. After investigating the looooong stack trace, I've discovered other errors regarding load error of some beans: Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'XXX_ds' is defined", where 'XXX_ds' is a name of datasource. – belgoros Jun 29 '16 at 12:57
  • \@Mihir Gohel: When defining `@ContextConfiguration`, at least one error less in IntelliJ: I can declare annotaded autowired controller as follows: `private DiagnosticsController diagnosticsController` with `@Autowired` annotation. – belgoros Jun 29 '16 at 14:14
  • Nope, there are other beans that Spring can not bind as well as a datasource not found issue. So the initial error saying ApplicationContext not found is still there. really weird :(. – belgoros Jun 30 '16 at 13:16
  • Can you try with edits i made in code. Not sure but hoping that it will solve the problem. Or you may share github repo link, i will have a look. – Mihir Gohel Jun 30 '16 at 14:34
0

src/main/webapp is not on the classpath, hence it can't find the file.

See Spring @ContextConfiguration how to put the right location for the xml for an explanation of why it's bad to put Spring configuration into webapp.

The solution would be to move your configuration into src/main/resources, and tweak however you're loading the Spring config files to look on the classpath for them. If you're using a web.xml file, that should be as simple as prefixing them with classpath:.

There are other solutions, but I feel that's the best option in the long-term.

Community
  • 1
  • 1
ipsi
  • 2,049
  • 18
  • 23
0

In order for me to get rid of the error "Failed to load applicationContext", I had to upgrade Spring to 4.3.6.RELEASE and JUnit to 4.12. This error happened to me when trying to run a JUnit test with Java 1.8 after I had introduced lambdas, even though the file was located in src/main/resources.

entpnerd
  • 10,049
  • 8
  • 47
  • 68
David B
  • 21
  • 1