Spring Top

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

>> LEARN SPRING

1. Overview

We consider a hybrid definition of beans in a Spring Boot application as 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 is not loaded in the test context.

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

2. “Failed to load ApplicationContext” Error

Let's reproduce the error by integrating 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:

Also, let's 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, let's 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 is not loaded in the test context. Moreover, the root cause is that the WEB-INF is not 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. Also, 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");
    }
}

Next, let's 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, let's 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've 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 described how to use XML-Based configuration files in test classes in a Spring Boot application. As always, the source code of the example we used 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
guest
0 Comments
Inline Feedbacks
View all comments