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

2023/05/12

1. 概述

在本快速教程中,我们将讨论如何从Spring Boot测试中排除自动配置类

Spring Boot的自动配置功能非常方便,因为它为我们处理了很多初始设置。但是,如果我们不希望某个自动配置干扰我们对模块的测试,这也可能是测试期间的一个问题。

这方面的一个常见示例是安全自动配置,我们也将在我们的例子中使用它。

2. 测试示例

首先,我们来看一下我们的测试示例。

我们拥有一个带有简单主页的Spring Boot Security应用程序,当我们尝试在没有身份验证的情况下访问主页时,响应w为“401 UNAUTHORIZED”。

我们可以在测试中通过使用RestAssured进行调用看到这一点:

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class AutoConfigIntegrationTest {
    @LocalServerPort
    private int port;

    @Test
    void givenNoAuthentication_whenAccessHome_thenUnauthorized() {
        int statusCode = RestAssured.get("http://localhost:" + port).statusCode();
        
        assertEquals(HttpStatus.UNAUTHORIZED.value(), statusCode);
    }
}

另一方面,我们可以在通过身份验证时成功访问主页:

@Test
void givenAuthenticationWhenAccessHomeThenSuccess() {
    int statusCode = RestAssured.given()
            .auth()
            .basic("john", "123")
            .get("http://localhost:" + port)
            .getStatusCode();
    
    assertEquals(HttpStatus.OK.value(), statusCode);
}

在以下小节中,我们将尝试不同的方法从测试配置中排除SecurityAutoConfiguration类

3. 使用@EnableAutoConfiguration注解

有多种方法可以从测试配置中排除特定的自动配置类。

首先,让我们看看如何使用@EnableAutoConfiguration(exclude={CLASS_NAME})注解

@ExtendWith(SpringExtension.class)
@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ExcludeAutoConfig3IntegrationTest {
    @LocalServerPort
    private int port;

    @Test
    void givenSecurityConfigExcluded_whenAccessHome_thenNoAuthenticationRequired() {
        int statusCode = RestAssured.get("http://localhost:" + port).getStatusCode();
        
        assertEquals(HttpStatus.OK.value(), statusCode);
    }
}

在此示例中,我们使用exclude属性排除了SecurityAutoConfiguration类,但我们可以对任何自动配置类执行相同的操作。

现在我们可以运行我们的测试,无需身份验证即可访问主页,并且它不会再失败。

4. 使用@TestPropertySource注解

接下来,我们可以使用@TestPropertySource注入属性“spring.autoconfigure.exclude”

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = {"spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration"})
class ExcludeAutoConfig1IntegrationTest {
    @LocalServerPort
    private int port;

    @Test
    void givenSecurityConfigExcluded_whenAccessHome_thenNoAuthenticationRequired() {
        int statusCode = RestAssured.get("http://localhost:" + port).getStatusCode();
        
        assertEquals(HttpStatus.OK.value(), statusCode);
    }
}

请注意,我们需要为属性指定完整的全限定类名(包名+类名)。

5. 使用profiles

我们还可以使用profile为我们的测试环境设置”spring.autoconfigure.exclude“

@ActiveProfiles("test")
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ExcludeAutoConfig2IntegrationTest {
    @LocalServerPort
    private int port;

    @Test
    void givenSecurityConfigExcluded_whenAccessHome_thenNoAuthenticationRequired() {
        int statusCode = RestAssured.get("http://localhost:" + port).getStatusCode();

        assertEquals(HttpStatus.OK.value(), statusCode);
    }
}

并在application-test.properties文件中包含所有特定于“test” profile相关的属性:

以下是我们的application-test.properties文件:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration

6. 使用自定义的测试配置类

最后,我们可以使用单独的配置应用程序类进行测试

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ExcludeAutoConfig4IntegrationTest {
    @LocalServerPort
    private int port;

    @Test
    void givenSecurityConfigExcluded_whenAccessHome_thenNoAuthenticationRequired() {
        int statusCode = RestAssured.get("http://localhost:" + port).getStatusCode();

        assertEquals(HttpStatus.OK.value(), statusCode);
    }
}

并从@SpringBootApplication(exclude={CLASS_NAME})中排除自动配置类:

@SpringBootApplication(scanBasePackages = "cn.tuyucheng.taketoday.boot", exclude = SecurityAutoConfiguration.class)
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}

7. 总结

在本文中,我们探讨了从Spring Boot测试中排除自动配置类的不同方法。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章