【发布时间】: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 在运行时执行的重要上下文自动配置。
【问题讨论】:
标签: java spring spring-boot junit spring-boot-test