belgoros
belgoros

Reputation: 3928

Fails to load Spring application context in tests with SpringJUnit4ClassRunner

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 {
...
}

Upvotes: 4

Views: 35611

Answers (4)

David B
David B

Reputation: 21

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.

Upvotes: 0

Sam Brannen
Sam Brannen

Reputation: 31267

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.

Upvotes: 2

Mihir Gohel
Mihir Gohel

Reputation: 316

This will work.

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

Upvotes: 1

ipsi
ipsi

Reputation: 2070

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.

Upvotes: 0

Related Questions