baeldung 2024-05-11
1. 概述
在本篇快速教程中,我们将讨论如何在 Spring Boot 测试中排除自动配置(auto-configuration)类。
Spring Boot 的自动配置功能非常方便,因为它为我们处理了大量的初始化设置。然而,在测试过程中,如果我们不希望某些自动配置干扰当前模块的测试,这种便利反而可能成为问题。
一个常见的例子是安全(Security)相关的自动配置,我们将在本文示例中使用它进行演示。
2. 测试示例
首先,我们来看一个测试示例。
我们有一个启用了安全保护的 Spring Boot 应用程序,其中包含一个简单的主页。
当我们在未认证的情况下尝试访问主页时,会收到 “401 UNAUTHORIZED” 响应。
让我们通过一个使用 REST-assured 发起请求的测试来验证这一点:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.DEFINED_PORT)
public class AutoConfigIntegrationTest {
@Test
public void givenNoAuthentication_whenAccessHome_thenUnauthorized() {
int statusCode = RestAssured.get("http://localhost:8080/").statusCode();
assertEquals(HttpStatus.UNAUTHORIZED.value(), statusCode);
}
}
另一方面,如果提供了身份认证信息,我们就可以成功访问主页:
@Test
public void givenAuthentication_whenAccessHome_thenOK() {
int statusCode = RestAssured.given().auth().basic("john", "123")
.get("http://localhost:8080/")
.statusCode();
assertEquals(HttpStatus.OK.value(), statusCode);
}
在接下来的章节中,我们将尝试多种方式从测试配置中排除 SecurityAutoConfiguration 类。
3. 使用 @EnableAutoConfiguration
有多种方法可以从测试配置中排除特定的自动配置类。
首先,我们来看看如何使用 @EnableAutoConfiguration(exclude={CLASS_NAME}) 注解:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.DEFINED_PORT)
@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
public class ExcludeAutoConfigIntegrationTest {
@Test
public void givenSecurityConfigExcluded_whenAccessHome_thenNoAuthenticationRequired() {
int statusCode = RestAssured.get("http://localhost:8080/").statusCode();
assertEquals(HttpStatus.OK.value(), statusCode);
}
}
在这个示例中,我们通过 exclude 属性排除了 SecurityAutoConfiguration 类。当然,这种方法也适用于其他任何自动配置类。
现在,我们可以运行无需身份认证即可访问主页的测试,并且它将不再失败。
4. 使用 @TestPropertySource
接下来,我们可以使用 @TestPropertySource 注入属性 spring.autoconfigure.exclude:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.DEFINED_PORT)
@TestPropertySource(properties =
"spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration")
public class ExcludeAutoConfigIntegrationTest {
// ...
}
注意:这里必须指定完整的类名(包括包名和简单类名)。
5. 使用配置文件(Profiles)
我们还可以通过配置文件(profiles)为测试设置 spring.autoconfigure.exclude 属性:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.DEFINED_PORT)
@ActiveProfiles("test")
public class ExcludeAutoConfigIntegrationTest {
// ...
}
并在 application-test.properties 文件中添加测试专用的属性:
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
6. 使用自定义测试配置
最后,我们可以为测试使用一个独立的配置类:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT)
public class ExcludeAutoConfigIntegrationTest {
// ...
}
并在该配置类中通过 @SpringBootApplication(exclude={CLASS_NAME}) 排除自动配置类:
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
7. 结论
在本文中,我们探讨了在 Spring Boot 测试中排除自动配置类的多种方法。