Failed to load ApplicationContext for JUnit test of Spring controller

336,011

Solution 1

As mentioned in the discussion: WEB-INF is not really part of the class path. If you use a common template, such as maven, use src/main/resources or src/test/resources to place the app-context.xml in. Then you can use classpath:.

Place your config file in src/main/resources/app-context.xml and use the following code:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:app-context.xml")
public class PersonControllerTest {
  ...
}

You can also create your test context with different configurations of beans.

Place your config file into src/test/resources/test-app-context.xml and use:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:test-app-context.xml")
public class PersonControllerTest {
  ...
}

Solution 2

There can be multiple root causes for this exception. For me, my mockMvc wasn't getting auto-configured. I solved this exception by using @WebMvcTest(MyController.class) at the class level. This annotation will disable full auto-configuration and instead apply only configuration relevant to MVC tests.

An alternative to this is, If you are looking to load your full application configuration and use MockMVC, you should consider @SpringBootTest combined with @AutoConfigureMockMvc rather than @WebMvcTest

Solution 3

If you are using Maven, add the below config in your pom.xml:

<build>
    <testResources>
                <testResource>
                    <directory>src/main/webapp</directory>
                </testResource>
    </testResources>
</build>

With this config, you will be able to access xml files in WEB-INF folder. From Maven POM Reference: The testResources element block contains testResource elements. Their definitions are similar to resource elements, but are naturally used during test phases.

Solution 4

In case you landed here based on the title, desperate for a solution and happen to be using Junit 5 Jupiter, you need to use

@ExtendWith(SpringExtension.class)

instead of

@RunWith(SpringJUnit4ClassRunner.class)
Share:
336,011

Related videos on Youtube

Saurabh
Author by

Saurabh

Updated on March 05, 2022

Comments

  • Saurabh
    Saurabh about 2 years

    I want to write a test case to check my controller (getPersons). This is a server side code. I have confusion what should i put inside @ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/app-contest.xml"})

    Secondly, I'm getting some errors like this:

    Failed to load application context. Can not find the path [which I specified in @ContextConfiguration]

    I have a structure like this:

     restAPI
        *src/main/java
          com.company.controller
             personController.java
        *Test
          com.company.testController
             personControllerTest.java
        *src
          main
           webapp
             WEBINF
               app-context.xml
    
    
    @Autowired
    private PersonService personService;
    
    @RequestMapping(value="/t2/{yy_id}/person", method=RequestMethod.GET)
    @ResponseBody
    public PersonInfo[] getPersons() {
    
        return personService.getPersons();
    }
    

    This is my Test

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations={"classpath:WEB-INF/app-context.xml"})
    @WebAppConfiguration
    public class PersonControllerTest  {
    
    
    @Autowired
    private WebApplicationContext wac;
    
    private MockMvc mockMvc;
    
    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }
    
    @Autowired
    private PersonService personService;
    
    @Test
    public void getPersons() throws Exception {
    
        this.mockMvc.perform(get("/t2/1/person")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk());
    
    }
    

    Trace

    java.lang.IllegalStateException: Failed to load ApplicationContext
        at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157)
        at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:103)
        at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:73)
        at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:313)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
        at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
        at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [WEB-INF/application-context.xml]; nested exception is java.io.FileNotFoundException: class path resource [WEB-INF/application-context.xml] cannot be opened because it does not exist
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:341)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:243)
        at org.springframework.test.context.web.GenericXmlWebContextLoader.loadBeanDefinitions(GenericXmlWebContextLoader.java:38)
        at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:113)
        at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:59)
        at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
        at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:248)
        at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:124)
        at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148)
        ... 24 more
    Caused by: java.io.FileNotFoundException: class path resource [WEB-INF/app-context.xml] cannot be opened because it does not exist
        at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:157)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:328)
    

    Can some one please help me out to figure it out what's wrong here?

    • Pavel Horal
      Pavel Horal almost 11 years
      I think that WEB-INF location should be loaded via file:/WEB-INF/... and not classpath:WEB-INF.
    • Saurabh
      Saurabh almost 11 years
      I have tried file as well still I'm getting the same eror
    • Jean-Philippe Bond
      Jean-Philippe Bond almost 11 years
      Are you sure it is not a spelling error? app-context.xml instead of app-contest.xml ;o
    • Saurabh
      Saurabh almost 11 years
      here in the question i have written by mistake contest but in my application it is context but its not working
    • Pavel Horal
      Pavel Horal almost 11 years
      Any chance you will post the actual exception / error with a stack trace?
    • Saurabh
      Saurabh almost 11 years
      I have post the actual stack trace so please suggest me something
    • JoseK
      JoseK almost 11 years
      With a similar structure, @ContextConfiguration(locations = "file:src/main/webapp/WEB-INF/app-context.xml") works for me. My test file is under src/test/java/com/company/** whereas yours seems to be under Test which is parallel to src
  • Saurabh
    Saurabh almost 11 years
    I'm using maven also in the project
  • Martin Strejc
    Martin Strejc almost 11 years
    Ok, I've edited and enhance my answer, so now you can apply it in your project, @Saurabh.
  • mcanti
    mcanti over 10 years
    In the first case you mentioned, you placed the app-context.xml file in src/main/resources. But when you run tests, it will not find it there, but src/test/resources. So where should it be placed for unit tests?
  • Martin Strejc
    Martin Strejc over 10 years
    Both src/test/* and src/main/* are present in the test phase of maven lifecycle if your POM is correct. Also you can change many thinks in maven. I rather use test-app-context.xml for testing and app-context.xml to separate their usage and content. Check stackoverflow.com/questions/6267312/… and maven.apache.org/guides/introduction/…
  • JDGuide
    JDGuide about 10 years
    My project do not have app-context.xml file. Only spring-servelt.xml and web.xml file.please help me how to solve the issue.
  • Martin Strejc
    Martin Strejc about 10 years
    I guess in your project file spring-servelt.xml is the spring context definition as well app-context.xml in the question.
  • Tim
    Tim over 7 years
    @ContextConfiguration("classpath*:**/applicationContext.xml"‌​) worked for me.
  • Dimitri Kopriwa
    Dimitri Kopriwa over 6 years
    I am not using xml, how do I do?
  • Martin Strejc
    Martin Strejc over 6 years
    If you use Java based Spring configuration I would suggest to ask a new question, because the answer is slightly different and would be hard to mix with this question/answer.
  • Ashikur Rahman
    Ashikur Rahman almost 4 years
    WebMvcTest(MyController.class) didn't work for me. But the alternate solution of adding SpringBootTest and AutoConfigureMockMvc worked me. Thanks.
  • pharask
    pharask almost 3 years
    @mahesh, you saved my day.