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

时间:2019-01-20 18:09:47

标签: java spring spring-boot junit spring-boot-test

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

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

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

   ...
}

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

  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() {}
    
    }
    

    由于测试框架在应用程序上下文之后 加载,因此似乎无法测试应用程序上下文无法加载。现在,我实际上编写了测试,手动确认测试失败,然后使用@Ignored进行注释,以免丢失。

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

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

    ConfigPropertiesAllValidTest
    ConfigPropertiesNoneSetTest
    ConfigPropertiesSomeValidSomeNotTest
    

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

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

2 个答案:

答案 0 :(得分:0)

您可以使用@ActiveProfiles批注和@SpringBootTest批注来加载不同配置文件的属性。这是课程级别,因此仅对您问题的情况1有帮助。

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

然后使用错误的配置创建一个application-badconfigtest.properties

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

答案 1 :(得分:0)