1. 概述

在本教程中,我们将讨论 如何在 Spring Boot 的测试环境中排除某些自动配置类(auto-configuration classes)

Spring Boot 的自动配置机制 是非常实用的,它能帮我们省去大量繁琐的配置工作。但在测试场景下,如果某些自动配置类干扰了我们对特定模块的测试逻辑,就需要将其排除掉。

最常见的例子就是安全相关的自动配置类——本文也将以 SecurityAutoConfiguration 为例进行演示。

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 类。同样的方式也可以用于其他任何 Spring Boot 提供的自动配置类

现在,即使不进行认证,也能成功访问首页接口。

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. 使用 Profile 配置

第三种方式是通过激活特定 Profile,在配置文件中设置排除项:

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

方法 描述
@EnableAutoConfiguration(exclude=...) 最直接的方式,适用于单个测试类
@TestPropertySource 通过属性注入实现,灵活性高
✅ Profile 配置 更适合多测试环境管理
✅ 自定义测试配置类 完全解耦测试与主应用配置

完整源码可从 GitHub 仓库 获取。


原始标题:Exclude Auto-Configuration Classes in Spring Boot Tests