Failed to load ApplicationContext for JUnit test of Spring controller
Asked Answered
O

9

52

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?

Opulence answered 20/6, 2013 at 17:50 Comment(7)
I think that WEB-INF location should be loaded via file:/WEB-INF/... and not classpath:WEB-INF.Afoot
I have tried file as well still I'm getting the same erorOpulence
Are you sure it is not a spelling error? app-context.xml instead of app-contest.xml ;oBoccie
here in the question i have written by mistake contest but in my application it is context but its not workingOpulence
Any chance you will post the actual exception / error with a stack trace?Afoot
I have post the actual stack trace so please suggest me somethingOpulence
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 srcApterous
A
29

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 {
  ...
}
Ataraxia answered 20/6, 2013 at 20:42 Comment(9)
I'm using maven also in the projectOpulence
Ok, I've edited and enhance my answer, so now you can apply it in your project, @Saurabh.Ataraxia
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?Mauriciomaurie
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 #6267812 and maven.apache.org/guides/introduction/…Ataraxia
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.Gustavogustavus
I guess in your project file spring-servelt.xml is the spring context definition as well app-context.xml in the question.Ataraxia
@ContextConfiguration("classpath*:**/applicationContext.xml") worked for me.Zoosperm
I am not using xml, how do I do?Woolfolk
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.Ataraxia
C
13

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

Centistere answered 11/2, 2019 at 15:27 Comment(2)
WebMvcTest(MyController.class) didn't work for me. But the alternate solution of adding SpringBootTest and AutoConfigureMockMvc worked me. Thanks.Turdine
thanks this worked for me bones tip , add @WithMockUser above the testing method or other wise the response will be 401 , unauthorizedJunction
F
4

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.

Feedback answered 27/6, 2015 at 3:46 Comment(0)
R
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)
Remembrance answered 4/3, 2022 at 21:21 Comment(0)
R
2

Try this with Junit5:

@SpringBootTest(classes = {ServletWebServerFactoryAutoConfiguration.class},
        webEnvironment = RANDOM_PORT,
        properties = {"spring.cloud.config.enabled=false"})
@ExtendWith(MockitoExtension.class)
@AutoConfigureMockMvc
Resolvable answered 7/6, 2022 at 14:46 Comment(0)
P
1

Sovled by editing the annotation

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
Patentee answered 27/1, 2023 at 11:16 Comment(0)
P
0

Using same version of spring boot and spring cloud dependency works for me.

Phthalein answered 5/8, 2022 at 8:36 Comment(0)
O
0

I was facing this issue after migrating to Junit 5 from Junit4.

For me this resolved the issue -

@TestPropertySource(properties = { "spring.config.location=classpath:application-test.yml" })

in

@SpringBootTest
@TestPropertySource(properties = { "spring.config.location=classpath:application-test.yml" })
class ApplicationTests {

    @Test
    void contextLoads() {
        assertTrue(true);
    }

}

where application-test.yml is located under src/test/resources

you also need to add this to @ActiveProfiles("test") all your test classes since I am using test profile (application-test.yml).

Omeara answered 12/3 at 10:8 Comment(0)
R
-7

Solved by adding the following dependency into pom.xml file :

<dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>test</scope>
</dependency>
Runic answered 4/1, 2019 at 10:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.