1. 概述
在本文中,我們將探討 Spring 中的 @WebAppConfiguration 註解,為什麼我們需要在集成測試中使用它,以及如何配置它,以便這些測試能夠啓動 WebApplicationContext。
2. @WebAppConfiguration
簡單來説,這是一個類級別的註解,用於在 Spring Framework 中創建一個 Web 版本的應用程序上下文。
它用於指示 ApplicationContext(用於測試的啓動上下文)應該是一個 WebApplicationContext 的實例。
關於使用説明的一點提示——我們通常會在集成測試中找到這個註解,因為 WebApplicationContext 用於構建 MockMvc 對象。關於 Spring 集成測試的更多信息,請參考這裏。
3. 加載 WebApplicationContext
從 Spring 3.2 版本開始,集成測試現在支持加載 WebApplicationContext。
@WebAppConfiguration
@ContextConfiguration(classes = WebConfig.class)
public class EmployeeControllerTest {
...
}
這會指示 TestContext 框架加載一個 WebApplicationContext 用於測試。
同時,在後台會創建一個 MockServletContext 並將其提供給 TestContext 框架中的 WebApplicationContext。
3.1 配置選項
默認情況下,<em>WebApplicationContext</em> 的基本資源路徑將被設置為 `“file:src/main/webapp”, 這是 Maven 項目中 WAR 文件根目錄的默認位置。
但是,我們可以通過簡單地為 <em itemprop="description">@WebAppConfiguration</em> 註解提供替代路徑來覆蓋此設置。
@WebAppConfiguration("src/test/webapp")我們還可以從類路徑引用一個基本資源路徑,而不是文件系統:
@WebAppConfiguration("classpath:test-web-resources")3.2. 緩存
一旦 WebApplicationContext 加載完成,它將被緩存並用於同一測試套件中所有聲明具有相同唯一上下文配置的後續測試。
有關緩存的更多詳細信息,請參閲參考手冊的 上下文緩存 部分。
4. 使用 @WebAppConfiguration 在測試中
現在我們已經理解了為什麼需要在測試類中添加 @WebAppConfiguration 註解,讓我們看看如果不添加它,使用 WebApplicationContext 時會發生什麼。
@RunWith(SpringJUnit4ClassRunner.class)
// @WebAppConfiguration omitted on purpose
@ContextConfiguration(classes = WebConfig.class)
public class EmployeeTest {
@Autowired
private WebApplicationContext webAppContext;
private MockMvc mockMvc;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.webAppContextSetup(webAppContext).build();
}
...
}請注意,我們註釋掉了該註解,以模擬遺漏添加該註解的情況。 這樣可以清楚地看到在運行 JUnit 測試時,測試會失敗的原因:我們嘗試在一個未設置 WebApplicationContext 的類中自動注入它
然而,一個更典型的例子是使用帶有 Web 支持的 Spring 配置的測試,這本身就足以使測試失敗。
讓我們來查看一下:
@RunWith(SpringJUnit4ClassRunner.class)
// @WebAppConfiguration omitted on purpose
@ContextConfiguration(classes = WebConfig.class)
public class EmployeeTestWithoutMockMvc {
@Autowired
private EmployeeController employeeController;
...
}儘管上述示例並未實現自動注入 <em >WebApplicationContext</em>,但仍然會失敗,因為它嘗試使用基於Web的配置 – <em >WebConfig</em>:
@Configuration
@EnableWebMvc
@ComponentScan("com.baeldung.web")
public class WebConfig implements WebMvcConfigurer {
...
}註解 @EnableWebMvc 是導致問題的原因——這需要一個啓用了 Web 的 Spring 上下文,如果沒有,測試將會失敗:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [javax.servlet.ServletContext] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true)}
at o.s.b.f.s.DefaultListableBeanFactory
.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373)
at o.s.b.f.s.DefaultListableBeanFactory
.doResolveDependency(DefaultListableBeanFactory.java:1119)
at o.s.b.f.s.DefaultListableBeanFactory
.resolveDependency(DefaultListableBeanFactory.java:1014)
at o.s.b.f.a.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement
.inject(AutowiredAnnotationBeanPostProcessor.java:545)
... 43 more因此,我們通過在測試中添加 @WebAppConfiguration 註解,輕鬆解決了這個問題。
5. 結論
在本文中,我們展示瞭如何使用 TestContext 框架,僅通過添加註解即可將 WebApplicationContext 加載到集成測試中。
最後,我們探討了即使添加了 @ContextConfiguration 註解到測試中,也無法正常工作的現象,前提是必須同時添加 @WebAppConfiguration 註解。