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

Spring Boot: How to override default properties in Unit tests

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

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

这是一个示例项目: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);
    }

}

或者测试包中的配置 class :

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

更新:

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

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

编辑

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

编辑:

好吧,我错了。元注释确实有效——我忘记设置保留策略,默认值为 CLASS。添加 @Retention(RUNTIME) 可以解决这个问题。

似乎没有办法在代码中全局设置它(即,没有在我的 IDE 中配置测试是如何 运行),所以我必须去现在使用配置文件。

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

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

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

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

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

将加载此 env 文件并将优先于默认 属性 文件 application.properties。请注意,默认文件仍将被加载,只是当发生 属性 碰撞时,环境特定 属性 文件优先,这意味着 application-staging.properties 或 [=19= 中指定的属性] 将覆盖 application.properties.

中的那些

每个测试 class 使用自己的配置文件,因此您需要为每个 class.

指定活动配置文件

您可能感兴趣的另一件事是,您可以通过 configuration classes

模拟服务
@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 ;
    }
}

在测试 classes 中,您可以使用多个活动配置文件: 例如@ActiveProfiles({"test", "mockEntityService"})

因此,您将使用模拟实现,而不是使用 EntityService 的真实实现。

您可以将 application.properties 添加到

src/test/resources

然后此文件中的所有属性都会覆盖 src/main/resources/application.properties.

中的这些属性

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