Spring Boot:如何在单元测试中覆盖默认属性

时间:2018-11-21 10:08:01

标签: java spring unit-testing spring-boot spring-boot-test

我尝试为我的单元测试加载第二个属性文件, 那会覆盖一些属性。

@PropertySource上用@Configuration加载它无效, 用@TestPropertySource加载它也不起作用。 只有直接在properties上设置@TesPropertySource才有效, 但是当我尝试将其制作为元注释时,它不起作用。

这是一个示例项目:https://github.com/cptwunderlich/SpringTestProperties

我希望将一个文件加载到所有测试中(例如使用@PropertySource),但是如果这样做不起作用,那么至少具有自定义的元注释会很好,所以我不必须将其放在每个测试中。 基本上,我想将一些数据导入测试数据库(spring.datasource.data),然后还要更改使用的数据库-无需复制整个配置,而必须在两个位置分别进行更改时间。

重要部分:

@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(locations = "classpath:application-test.properties")
public class TestconfigApplicationTests {

    @Value("${my.test.property}")
    private String testproperty;

    @Test
    public void assertValue() {
        Assert.assertEquals("foobar", testproperty);
    }

}

或者在测试包中的配置类

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
@PropertySource("classpath:application-test.properties")
public class GlobalTestConfig {
}

更新

答案中的主要建议是使用@ActiveProfile激活“测试”配置文件,这将导致加载“ application-test.yaml”。 这比@TestPropertySource更好,但是我仍然需要在每个测试类上添加一个注释。我尝试创建一个元注释-should work-因此,至少我只有一个自定义注释,可以在其中捆绑其他设置。但这不起作用。

理想的解决方案是使用一个配置类全局设置这些设置,而不必在每个测试上都添加注释。 我仍在寻找该解决方案,或者至少在关闭此问题之前调试元注释。 编辑:我创建了一个Jira问题:SPR-17531

编辑

好的,我有点困惑,所以我重新测试了所有不同的组合:

  • @TestPropertySource(locations = "classpath:application-test.properties")在测试中,实际上现在有效。嗯。
  • @ActiveProfiles("test")在测试中有效。
  • 使用@ActiveProfiles
  • 元注释无效起作用。编辑:它确实...
  • 任何形式的全局配置(TestPropertySource,ActiveProfiles,Propertysource)不起作用
  • (在test / resources中具有application.properties也不起作用,bc。它不会覆盖单个属性,但是会覆盖整个文件,即,我需要重新定义和复制所有内容。)

编辑:

好的,我的错。元注释确实起作用-我忘记设置保留策略,默认设置为CLASS。添加@Retention(RUNTIME)可以解决此问题。

似乎没有一种方法可以在代码中进行全局设置(即,无需在IDE中配置测试的运行方式),所以我现在必须使用配置文件。

2 个答案:

答案 0 :(得分:4)

您可以使用@ActiveProfiles("test")。这会将application-test.yml属性设置为测试环境。

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class TestconfigApplicationTests {
    ...
}

如果我们需要针对不同的环境,则Boot中有一个内置机制,因此不需要其他库或重构。

我们可以简单地在application-environment.properties目录中定义一个src/main/resources文件,然后使用相同的环境名称设置一个Spring配置文件。

例如,如果我们定义一个stagingtest环境,则意味着我们必须定义一个暂存或测试配置文件,然后定义application-staging.propertiesapplication-test.properties

env文件将被加载,并优先于默认属性文件application.properties。请注意,默认文件仍将被加载,只是当发生属性冲突时,特定于环境的属性文件优先,这意味着application-staging.propertiesapplication-test.properties中指定的属性将覆盖{{ 1}}。

每个测试类都使用自己的配置文件,因此您需要为每个类指定活动配置文件。

您可能还需要关注的另一件事是,您可以通过application.properties类来模拟服务

configuration

在测试课程中,您可以使用多个活动配置文件: 例如@Configuration @Profile("mockEntityService") public class EntityServiceMockProvider { @Bean @Primary public EntityService entityService() { EntityService mockedEntityService = Mockito.mock(EntityService.class); Entity entity= Mockito.mock(Entity.class); when(mockedEntityService.save(any(Entity.class))) .thenReturn(entity); return mockedEntityService ; } }

因此,将使用模拟的实现,而不是使用@ActiveProfiles({"test", "mockEntityService"})的实际实现。

答案 1 :(得分:0)

您可以将application.properties添加到

src/test/resources

然后,此文件中的所有属性将覆盖src / main / resources / application.properties中的这些属性。

因此,您不需要配置文件和任何其他注释,例如@TestPropertySource