Spring Top

Get started with Spring 5 and Spring Boot 2, through the reference Learn Spring course:

>> LEARN SPRING

1. Overview

The hybrid definition of beans in a Spring Boot application is one that includes both an Annotation-Based and XML-Based configuration. In this environment, we may want to use the XML-Based configuration in the test classes. However, sometimes in this situation, we may encounter the application context loading error “Failed to load ApplicationContext.” This error appears in the test classes because the application context isn't loaded in the test context.

In this tutorial, we'll discuss how to integrate the XML application context into testing in a Spring Boot application.

Further reading:

Testing in Spring Boot

Learn about how the Spring Boot supports testing, to write unit tests efficiently.

Integration Testing in Spring

A quick guide to writing integration tests for a Spring Web application.

Spring Boot Error ApplicationContextException

Learn how to solve the ApplicationContextException in Spring Boot.

2. “Failed to load ApplicationContext” Error

Let's reproduce the error by integrating the XML-Based application context in a Spring Boot application.

First, let's suppose we have an application-context.xml file with the definition of a service bean:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd">
	  
    <bean id="employeeServiceImpl" class="com.baeldung.xmlapplicationcontext.service.EmployeeServiceImpl" />
</beans>

Now we can add the application-context.xml file in the webapp/WEB-INF/ location:

We'll also create a service interface and class:

public interface EmployeeService {
    Employee getEmployee();
}

public class EmployeeServiceImpl implements EmployeeService {

    @Override
    public Employee getEmployee() {
        return new Employee("Baeldung", "Admin");
    }
}

Finally, we'll create a test case for getting the EmployeeService bean from the application context:

@RunWith(SpringRunner.class)
@ContextConfiguration(locations={"classpath:WEB-INF/application-context.xml"})
public class EmployeeServiceAppContextIntegrationTest {

    @Autowired
    private EmployeeService service;

    @Test
    public void whenContextLoads_thenServiceISNotNull() {
        assertThat(service).isNotNull();
    }

}

Now if we try to run this test, we'll observe the error:

java.lang.IllegalStateException: Failed to load ApplicationContext

This error appears in the test classes because the application context isn't loaded in the test context. Moreover, the root cause is that the WEB-INF isn't included in the classpath:

@ContextConfiguration(locations={"classpath:WEB-INF/application-context.xml"})

3. Using an XML-Based ApplicationContext in Test

Let's see how we can use an XML-Based ApplicationContext in test classes. We have two options to use the XML-Based ApplicationContext in the test: @SpringBootTest and @ContextConfiguration annotations.

3.1. Test Using @SpringBootTest and @ImportResource

Spring Boot provides the @SpringBootTest annotation, which we can use to create an application context to be used in a test. In addition, we must use @ImportResource in the Spring Boot main class for reading XML beans. This annotation allows us to import one or more resources containing bean definitions.

First, let's use the @ImportResource annotation in the main class:

@SpringBootApplication
@ImportResource({"classpath*:application-context.xml"})

Now let's create a test case for getting EmployeeService bean from the application context:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = XmlBeanApplication.class)
public class EmployeeServiceAppContextIntegrationTest {

    @Autowired
    private EmployeeService service;

    @Test
    public void whenContextLoads_thenServiceISNotNull() {
        assertThat(service).isNotNull();
    }

}

The @ImportResource annotation loads XML beans located in the resource directory. In addition, the @SpringBootTest annotation loads the whole application's beans in the test class. Therefore, we're able to access the EmployeeService bean in the test class.

3.2. Test Using @ContextConfiguration With resources

We can create our test context with different configurations of beans by placing our test configuration file in the src/test/resources directory.

In this case, we use the @ContextConfiguration annotation for loading the test context from the src/test/resources directory.

First, let's create another bean from the EmployeeService interface:

public class EmployeeServiceTestImpl implements EmployeeService {

    @Override
    public Employee getEmployee() {
        return new Employee("Baeldung-Test", "Admin");
    }
}

Then we'll create the test-context.xml file in the src/test/resources directory:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd">
	
    <bean id="employeeServiceTestImpl" class="process.service.EmployeeServiceTestImpl" />
</beans>

Finally, we'll create the test case:

@SpringBootTest
@ContextConfiguration(locations = "/test-context.xml")
public class EmployeeServiceTestContextIntegrationTest {

    @Autowired
    @Qualifier("employeeServiceTestImpl")
    private EmployeeService serviceTest;

    @Test
    public void whenTestContextLoads_thenServiceTestISNotNull() {
        assertThat(serviceTest).isNotNull();
    }

}

Here we loaded employeeServiceTestImpl from the test-context.xml using the @ContextConfiguration annotation.

3.3. Test Using @ContextConfiguration With WEB-INF

We can also import an application context in the test classes from the WEB-INF directory. To do this, we can address the application context using its file URL:

@RunWith(SpringRunner.class)
@ContextConfiguration(locations = "file:src/main/webapp/WEB-INF/application-context.xml")

4. Conclusion

In this article, we learned how to use XML-Based configuration files in test classes in a Spring Boot application. As always, the source code used in this article is available over on GitHub.

Spring bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> THE COURSE
Junit footer banner
Comments are closed on this article!