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

Ada*_*hes 5 java junit spring spring-boot spring-boot-test

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

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

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

   ...
}
Run Code Online (Sandbox Code Playgroud)

在测试此类应用程序时,我会在没有模拟的情况下启动完整或部分应用程序上下文,因为上下文和验证本身很复杂 - 模拟无法捕获这一点。不幸的是,我不断发现这种模式有两个限制:

  1. 我们如何测试错误的配置是否无法加载?

    想象一下测试该端口无效,因为它不在 的限制范围内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() {}
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

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

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

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

    ConfigPropertiesAllValidTest
    ConfigPropertiesNoneSetTest
    ConfigPropertiesSomeValidSomeNotTest
    
    Run Code Online (Sandbox Code Playgroud)

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

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