1. 概述
Spring Boot 應用中,Bean 的混合定義是指同時包含基於註解(Annotation-Based)和基於 XML 的配置。 在這種環境下,我們可能需要在測試類中使用基於 XML 的配置。 但是,有時在這種情況中,我們可能會遇到應用程序上下文加載錯誤“Failed to load ApplicationContext.”。 這種錯誤出現在測試類中,因為測試上下文未加載應用程序上下文。
在本教程中,我們將討論 如何在 Spring Boot 應用中集成 XML 應用程序上下文到測試中。
“無法加載 ApplicationContext” 錯誤
讓我們通過在 Spring Boot 應用程序中集成基於 XML 的應用程序上下文來重現此錯誤。
首先,假設我們有一個名為 application-context.xml 的文件,其中定義了一個服務 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>
現在我們可以將 application-context.xml 文件添加到 webapp/WEB-INF/ 目錄下:
我們還將創建服務接口和類:
public interface EmployeeService {
Employee getEmployee();
}
public class EmployeeServiceImpl implements EmployeeService {
@Override
public Employee getEmployee() {
return new Employee("Baeldung", "Admin");
}
}最後,我們將創建一個用於從應用程序上下文中獲取 EmployeeService 豆的測試用例:
@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();
}
}現在如果我們嘗試運行此測試,我們將觀察到錯誤:
java.lang.IllegalStateException: Failed to load ApplicationContext這段代碼錯誤出現在測試類中,因為測試上下文未加載應用程序上下文。 此外,根本原因是 WEB-INF 未包含在類路徑中。
@ContextConfiguration(locations={"classpath:WEB-INF/application-context.xml"})3. 使用基於 XML 的 ApplicationContext 進行測試
讓我們看看如何使用基於 XML 的 ApplicationContext 在測試類中使用。 在測試中,我們有以下兩個選項來使用基於 XML 的 ApplicationContext:@SpringBootTest 註解和 @ContextConfiguration 註解。
3.1. 使用 @SpringBootTest 和 @ImportResource 進行測試
Spring Boot 提供 的 @SpringBootTest 註解,我們可以使用它來創建一個用於測試的應用上下文。 此外,我們必須在 Spring Boot 主類中使用 @ImportResource 註解來讀取 XML 豆本。 這個註解允許我們導入一個或多個包含豆本定義的資源。
第一,讓我們在主類中使用 @ImportResource 註解:
@SpringBootApplication
@ImportResource({"classpath*:application-context.xml"})現在,讓我們創建一個測試用例,用於從應用程序上下文中獲取 EmployeeService Bean:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = XmlBeanApplication.class)
public class EmployeeServiceAppContextIntegrationTest {
@Autowired
private EmployeeService service;
@Test
public void whenContextLoads_thenServiceISNotNull() {
assertThat(service).isNotNull();
}
}@ImportResource 註解加載位於 resource 目錄下的 XML Bean。 此外,@SpringBootTest 註解會在測試類中加載整個應用程序的所有 Bean。 因此,我們可以在測試類中訪問 EmployeeService Bean。
3.2. 使用 @ContextConfiguration 和 resources 進行測試
我們可以通過將測試配置文件的放置在 src/test/resources 目錄下,創建具有不同 Bean 配置的測試上下文。
在這種情況下,我們使用 @ContextConfiguration 標註來從 src/test/resources 目錄加載測試上下文。
首先,讓我們從 EmployeeService 接口創建一個 Bean:
public class EmployeeServiceTestImpl implements EmployeeService {
@Override
public Employee getEmployee() {
return new Employee("Baeldung-Test", "Admin");
}
}
然後我們將會在 src/test/resources 目錄下創建 test-context.xml 文件:
<?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>
最後,我們將創建測試用例:
@SpringBootTest
@ContextConfiguration(locations = "/test-context.xml")
public class EmployeeServiceTestContextIntegrationTest {
@Autowired
@Qualifier("employeeServiceTestImpl")
private EmployeeService serviceTest;
@Test
public void whenTestContextLoads_thenServiceTestISNotNull() {
assertThat(serviceTest).isNotNull();
}
}我們使用帶有 employeeServiceTestImpl 註解的 test-context.xml 加載了這個測試實現。
3.3. 使用 @ContextConfiguration 與 WEB-INF 進行測試
我們也可以在測試類中從 WEB-INF 目錄導入應用程序上下文。要做到這一點,我們可以使用其 文件 URL 來引用應用程序上下文:
@RunWith(SpringRunner.class)
@ContextConfiguration(locations = "file:src/main/webapp/WEB-INF/application-context.xml")4. 結論
在本文中,我們學習瞭如何在 Spring Boot 應用程序的測試類中使用基於 XML 的配置文件。