SpringBootTest - 如何在测试级别断言上下文不加载和更改属性?

Posted

技术标签:

【中文标题】SpringBootTest - 如何在测试级别断言上下文不加载和更改属性?【英文标题】:SpringBootTest - how to assert context not loads and change properties at test level? 【发布时间】:2019-06-14 05:16:54 【问题描述】:

在测试应用程序配置时,我非常依赖@SpringBootTest。应用程序属性可能很复杂,具有默认值和重要的验证。例如:

prop:
  ports: 1205,2303,4039
  fqdn: $server.host:$ports[0]/$path

@Configuration
SomeConfigClass
   @Value"$ports:#collections.emptyList"
   List<Integer> ports;

   ...

在测试此类应用程序时,我会调出不带模拟的完整或部分应用上下文,因为上下文和验证本身很复杂 - 模拟不会捕捉到这一点。不幸的是,我一直发现这种模式有两个限制:

    我们如何测试错误的配置加载失败

    假设测试端口无效,因为它不在500 - 1500 的限制范围内。

    @SpringBootTest(
            classes = SomeConfigClass.class,
            properties = "port=9000"
    )
    public class BadConfigTest
    
        @Test(expected = ApplicationContextFailedException.class)
        public void WHEN_port_9000_THEN_appcontext_fails_to_load() 
    
    
    

    由于测试框架在应用程序上下文之后加载,似乎没有办法测试应用程序上下文加载失败。现在我实际编写测试,手动确认它们失败,然后用@Ignored 注释,这样它们就不会丢失。

    如何在测试方法而不是类级别更改属性?

    @SpringBootTest 是一个类注解,意味着应用程序属性绑定在测试类级别。这导致需要针对许多属性集的测试类,并使测试套件膨胀。例如,我最终会得到如下测试类:

    ConfigPropertiesAllValidTest
    ConfigPropertiesNoneSetTest
    ConfigPropertiesSomeValidSomeNotTest
    

    其中每一个都只有一个或两个测试用例。最好有一个 ConfigPropertiesTest 类,每个测试都有不同的道具。这可能吗?

再次 - 我想避免模拟,因为它们不会捕获 Spring 在运行时执行的重要上下文自动配置。

【问题讨论】:

【参考方案1】:

我们最终使用了本文档中描述的ApplicationContextRunner

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html#boot-features-test-autoconfig

【讨论】:

Adam - 谢谢你的问题(写得很好)和你自己对你问题的回答:)它对我帮助很大。对于搜索有关ApplicationContext 测试信息的人,还有关于ApplicationContextRunner baeldung.com/spring-boot-context-runner 的文章/指南,还有AssertableWebApplicationContextAssertableReactiveWebApplicationContext 类在测试网络时可能会有所帮助应用上下文。还值得一提的是,ApplicationContextRunner2.0.0 版本的spring-boot-test 开始可用。【参考方案2】:

您可以使用@ActiveProfiles 注释和@SpringBootTest 注释来加载不同配置文件的属性。这是班级级别,因此仅对您问题的案例 1 有所帮助。

@SpringBootTest(classes = SomeConfigClass.class)
@ActiveProfiles("badconfigtest")
public class BadConfigTest
    ...

然后有一个带有错误配置的application-badconfigtest.properties

我认为您不会找到一种方法来更改同一类中的测试方法之间的属性。您可以使用@DirtiesContext 重新加载应用程序上下文,但我还没有看到使用不同属性文件的方法。我猜你可以将值注入到已经加载了属性的配置类中。

【讨论】:

谢谢 - 我已经使用了 @ActiveProfiles 注释,但它并没有太大的区别,因为它仍然迫使我将一组属性绑定到一个测试类

以上是关于SpringBootTest - 如何在测试级别断言上下文不加载和更改属性?的主要内容,如果未能解决你的问题,请参考以下文章

一分钟上手SpringBootTest

Spring Boot 2.x 实践记:@SpringBootTest

Spring Boot 2.x 实践记:@SpringBootTest

Spring Boot 2.x 实践记:@SpringBootTest

调试器、@SpringBootTest 和 Gradle

SpringBootTest 用于 DAO JUnit 测试