通过配置文件使用Yaml属性进行Spring Boot测试

时间:2018-06-21 09:55:08

标签: java spring configuration-files

因此,在这个主题上有很多热门话题,但没有一个对我有用。

我有一个非常简单的配置类:

@Configuration
@ConfigurationProperties(prefix = "props")
public class TagIncluder {

    private static final String PARAMETER_NAME = "tags";

    private List<String> tags;

    public TagIncluder() {
        tags = new ArrayList<>();
    }

    public List<String> getTags() {
        return tags;
    }

    @Handler
    public void attachIncludedTags(Exchange exchange) {
        exchange.getIn().setHeader(PARAMETER_NAME, tags);
    }
}

我希望此类能够加载不同的属性文件。我正在使用yaml,我的文件名为application-tag_test.yml。我曾尝试将此文件放置在src/main/resourcessrc/test/resourcessrc/test/resources/config中,但从未将其取出。

这是属性文件的内容:

props:
  tags:
    - test 

最后是测试用例:

@SpringBootTest
@ActiveProfiles("tag_test")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TagIncluder.class)
public class TagIncluderTest extends ExchangeTestSupport {

    @Autowired
    private TagIncluder sut;

    @Test
    public void attachIncludedTags_shouldUseTagsInFileIfFileSpecified() {
        Exchange testExchange = createExchange();
        sut.attachIncludedTags(testExchange);

        Assertions.assertThat(testExchange.getIn().getHeader("tags", List.class))
            .size().isGreaterThanOrEqualTo(1);
    }
}

此外,我尝试将application.properties文件放置在上述位置,内容如下:

spring.profiles.active=tag_test

Spring将我的yaml文件设置为被测类的所需配置是什么?

更新

因此,在进行了一些探索和反复试验之后,我发现以下工作有效:

@SpringBootTest
@ActiveProfiles("tag_test")
@RunWith(SpringJUnit4ClassRunner.class)
public class TagIncluderTest extends ExchangeTestSupport {

    @Autowired
    private TagIncluder sut;

    @Test
    public void attachIncludedTags_shouldUseTagsInFileIfFileSpecified() {
        Exchange testExchange = createExchange();
        sut.attachIncludedTags(testExchange);

        Assertions.assertThat(testExchange.getIn().getHeader("tags", List.class))
            .size().isGreaterThanOrEqualTo(1);
    }
}

这里的区别是我删除了@ContextConfiguration批注,让Spring处理了所有这些。

这要慢很多,我宁愿指定需要的东西。我认为这种情况将来可能会中断,例如,如果我添加另一个将从整个上下文开始的配置类并抛出错误,因为这些属性未包含在我的application-tag_test.yml配置中。

最后,我尝试用于配置的上述任何位置都适用于以上注释。不需要application.properties来指定配置文件。

如果有人知道指定将什么加载到上下文中的方法,我将不胜感激另一个解决方案。

2 个答案:

答案 0 :(得分:2)

在上述Jans建议的指导下,我设法将测试隔离了下来。自动配置的测试是围绕here编写的,但是仅涉及Springs预定义的@..Test注释。

例如,如果您深入研究@WebMvcTest,将会发现@ImportAutoConfiguration注释。

使用此代码,我们可以告诉测试类为应用程序的单个 slice 启用自动配置。 here提供了教程。可用于自动配置的工厂的完整列表可以在spring-boot repository中找到。

最后,这是整个测试课程:

@ActiveProfiles("tag_test")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TagIncluder.class)
@ImportAutoConfiguration(classes = ConfigurationPropertiesAutoConfiguration.class)
public class TagIncluderTest extends ExchangeTestSupport {

    @Autowired
    private TagIncluder sut;

    @Test
    public void attachIncludedTags_shouldUseTagsInFileIfFileSpecified() {
        Exchange testExchange = createExchange();
        sut.attachIncludedTags(testExchange);

        Assertions.assertThat(testExchange.getIn().getHeader("tags", List.class))
            .size().isGreaterThanOrEqualTo(1);
    }
}

要测试的课程未触及。

现在我们可以:

  • 使用个人资料
  • 使用Yaml
  • 在Spring Context中仅测试所需的类

这很有启发性:)

答案 1 :(得分:1)

Spring Boot Test文档指出

External properties, logging, and other features of Spring Boot are installed in the context by default only if you use SpringApplication to create it.

这意味着您需要具有一个正常运行的Spring Boot应用程序,才能测试与测试用例中的属性加载相关的任何东西。

此外,从属性设置列表需要一个setter。这有效:

@Configuration
@ConfigurationProperties(prefix = "props")
public class TagIncluder {
    private List<String> tags;

    public void setTags(List<String> tags) {
        this.tags = tags;
    }

    public List<String> getTags() {
        return tags;
    }
}

@Component
public class MyComponent {
    @Autowired
    TagIncluder tagIncluder;
}

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

@SpringBootTest
@ActiveProfiles("tag_test")
@RunWith(SpringRunner.class)
public class TagIncluderTest {

    @Autowired
    private TagIncluder sut;

    @Test
    public void attachIncludedTags_shouldUseTagsInFileIfFileSpecified() {
        System.out.println(sut.getTags());
    }
}