在 Spring Boot 测试中排除自动配置类

更新于 2025-12-30

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 测试中排除自动配置类的多种方法。