如何在 Spring Boot 和 JUnit 测试中定义 spring.config.location?

     2023-02-27     144

关键词:

【中文标题】如何在 Spring Boot 和 JUnit 测试中定义 spring.config.location?【英文标题】:How to define the spring.config.location on Spring Boot and JUnit tests? 【发布时间】:2019-02-08 01:16:17 【问题描述】:

在运行 JUnit 测试时,我们如何以编程方式配置 Spring Boot 以定义 spring.config.namespring.config.location 属性的新值?

例如,如果我们想在运行应用程序时定义这些属性,我们可以使用类似(在 Kotlin 中):

fun main(args: Array<String>) 
//  SpringApplication.run(Application::class.java, *args)

    val applicationContext = SpringApplicationBuilder(Application::class.java)
        .properties(
            """spring.config.name:
                $getSpringConfigNames()
            """,
            """spring.config.location:
                $getSpringConfigLocationPaths()
            """
        )
        .build()
        .run(*args)

//  val environment = applicationContext.getEnvironment()

但我无法找到一种方法来配置它以在 JUnit 测试中使用。

编辑

由于弹簧靴的限制,这里有一个复杂的问题。

我想使用整个文件夹及其子文件夹作为搜索配置文件的有效位置(例如,我们可以拥有用于特定环境、数据库、第三方等的文件夹)。

在运行应用程序时,可以创建一个方法,在本例中为 getSpringConfigLocationPaths()。并且此方法创建一个逗号分隔的列表,其中包含“主”文件夹内的所有文件夹。

例如,对于主文件夹src/main/resources/configuration,它将输出:

src/main/resources/configuration,
src/main/resources/configuration/environments,
src/main/resources/configuration/environments/development,
src/main/resources/configuration/environments/staging,
src/main/resources/configuration/environments/testing,
src/main/resources/configuration/environments/production,
src/main/resources/configuration/environments/common

在使用 JUnit 测试和 Spring Boot 时,我们如何解决这种情况?

不幸的是 Spring Boot 不允许 src/main/resources/configuration/**/* 之类的东西。

因为我们在不同的子文件夹中使用多个属性文件来组织系统,所以我们需要找到一种方法来动态地考虑它们。

【问题讨论】:

【参考方案1】:

我正在使用最新的 Spring Boot 2.2.0,根据我的经验,@TestPropertySource@SpringBootTest 注释都可以完成这项工作,因为它们具有 properties 属性。 所以,你可以这样做:

@TestPropertySource(properties = ["spring.config.location=classpath:dev/", "spring.config.name=custom-app-name"]
@TestConfiguration
class DevTestCfg  // this will make tests to look for configs in resources/dev/custom-app-name.properties

如果您希望从多个位置加载您的属性,请注意有一个 spring.config.additional-location 属性。

这里唯一的问题是properties 属性中的值必须是常量。 但是您可以为每个环境创建多个配置,并在每个配置类上放置对应的@Profile("envName")。然后用不同的-Dspring.profiles.active 运行你的测试,相应的测试配置应该会自动拾取。

【讨论】:

【参考方案2】:

应该仔细设计运行 spring boot 的测试, spring boot 测试有一个完整的测试框架,所以显然可以考虑使用这个框架。

在配置管理方面,我建议考虑以下几点:

基本上有两种类型的测试:

加载具体特定配置(bean 集)的测试,例如,如果您只想测试 DAO,则加载此 dao 的配置。 在这种情况下,配置应该根据特定测试的需要“量身定制”,而不需要“完整”配置。

例如,如果微服务包含数据库配置(用户、密码、模式等)以及消息管理,则在测试 DAO、消息传递时无需指定消息传递系统的配置无论如何都不会加载bean。

通常,这种“类型”的测试会是这样的:

@SpringBootTest(classes = RelationalDbDaoConfiguration.class) 
public class MyDaoTest 


如果您没有满足您需要的配置,您可以使用@MockBean 模拟不必要的bean,甚至在src/test/java 中创建自定义配置,以便它只在测试类路径中。使用@TestConfiguration 是有意义的,但它超出了问题的范围。

现在为了只为 db 加载配置,有很多选项,仅举几例:

@ActiveProfiles("dao") 在测试类上 + 将“application-dao.properties/yaml”放入src/test/resourcessrc/test/resources/config

在测试中使用@TestPropertySource(locations = "classpath:whatever.properties")

创建一个特殊的“DbProperties”bean 并在 Spring 中以编程方式对其进行初始化,当您了解有关仅在实际测试执行期间运行测试的上下文的一些详细信息时(例如,如果您开始测试前的数据库和端口是动态创建的,但它确实是一个相当高级的设置,超出了这个问题的范围)+数据源 bean 可以读取这些属性

使用@SpringBootTestproperties 属性提供“细粒度”属性定义

有点明显,但我还是要提一下:将application.properties 放入src/test/resources 它将覆盖常规配置

第二种类型的测试是当你加载“整个”微服务时,通常,这些是在@SpringBootTest注解中没有“classes”参数的测试

@SpringBootTest // note, no actual configurations specified
public class MyMicroserviceTest 
  ...

现在,这肯定需要指定一整套配置,尽管实际指定这些配置的技术仍然适用(只是配置文件的内容会有所不同)。

我不建议在测试过程中使用spring.config.location,因为这意味着测试依赖于一些外部资源,这使得整个设置更加复杂。

【讨论】:

嗨,马克,感谢您的解决方案。我应该多解释一下为什么我需要这个(主要问题与 spring.config.location 属性中要考虑的动态文件夹有关)。你知道我们能不能做点什么? 好吧,例如在@TestPropertySource 方法中有一个“位置”属性,因此您可以指定配置【参考方案3】:

如果是 XML 驱动的配置,

@ContextConfiguration(locations = "/app-context.xml")

如果是配置类驱动的注解,

@ContextConfiguration(classes = AppCOnfig::class, AnotherCOnfig::class

这些将在您运行的单元测试类的类级别上定义。

此外,如果您有可供 Junit 考虑的个人资料, @ActiveProfiles("myProfile") 将被添加到测试类中。

【讨论】:

您好 Karthik R,感谢您的解决方案。我应该多解释一下为什么我需要这个(主要问题与 spring.config.location 属性中要考虑的动态文件夹有关)。你知道我们能不能做点什么? 我看到了你更新的问题。您不需要为 Spring Boot 测试提供多个文件。我明白你想要做什么。您正在尝试测试所有环境配置。但是单元测试不应该这样做。您可以使用 spring.profiles.include 将一个配置文件包含在另一个配置文件中,但是如果您重复相同的配置,这会产生冲突。 如果您的目标是尝试测试所有环境配置,我不建议您尝试。您基于配置文件(dev、qa 等)的配置应该只因外部参数(如 DB url 等)而有所不同,但您的单元测试不应该担心它。要么模拟这些外部因素,要么只针对一种环境进行测试,比如本地。希望我没有误解你的问题。

如何在单个 JUnit 测试中运行两个 Spring Boot 微服务?

】如何在单个JUnit测试中运行两个SpringBoot微服务?【英文标题】:HowtoruntwoSpringBootmicroservicesinasingleJUnittest?【发布时间】:2018-06-0101:32:29【问题描述】:我有两个SpringBootREST微服务,我们称它们为A和B。我们还假设A对B进行REST调用... 查看详情

如何使用junit在spring-boot中测试常见错误ErrorController

】如何使用junit在spring-boot中测试常见错误ErrorController【英文标题】:HowtotestcommonerrorErrorControllerinspring-bootwithjunit【发布时间】:2017-08-0307:52:58【问题描述】:在一个SpringBoot项目中,我想用Junit测试我的ErrorController。代码如下sn-p... 查看详情

如何在spring-boot应用程序的junit中调用ApplicationContextInitializer

】如何在spring-boot应用程序的junit中调用ApplicationContextInitializer【英文标题】:HowtoinvokeApplicationContextInitializerinjunitofspring-bootapplication【发布时间】:2018-07-1906:21:21【问题描述】:我是spring-boot的新手,并基于squiggly实现了一个带有... 查看详情

用于 Spring Boot 应用程序的 JUnit @BeforeClass 非静态工作

】用于SpringBoot应用程序的JUnit@BeforeClass非静态工作【英文标题】:JUnit@BeforeClassnon-staticworkaroundforSpringBootapplication【发布时间】:2016-01-0208:41:56【问题描述】:如果您希望JUnit的@BeforeClass注释在所有@Test方法之前运行一次,则必须... 查看详情

如何使用 JUnit 在 Spring Boot 中的公共方法中模拟私有方法

】如何使用JUnit在SpringBoot中的公共方法中模拟私有方法【英文标题】:HowtomockprivatemethodinpublicmethodinSpringBootwithJUnit【发布时间】:2019-01-0911:04:21【问题描述】:我想问你几个问题并征求你的意见:我想测试我的公共方法(我使用... 查看详情

在 Kotlin 和 JUnit5 中测试 Spring Boot 缓存

】在Kotlin和JUnit5中测试SpringBoot缓存【英文标题】:TestSpringBootcacheinKotlinandJUnit5【发布时间】:2020-12-0410:57:24【问题描述】:我有一个简单的存储库,它是用Kotlin编写的用于从db获取站点列表的界面;我用Spring缓存缓存响应:interf... 查看详情

如何 JUnit 测试 Spring-Boot 的 Application.java

】如何JUnit测试Spring-Boot的Application.java【英文标题】:HowtoJUnitTestSpring-Boot\'sApplication.java【发布时间】:2017-06-0602:54:23【问题描述】:道歉,因为这似乎是一个无用的行为,但是我们有什么办法可以在Spring-Boot(1.3.8.RELEASE)的Applicati... 查看详情

Maven 依赖于 Spring Boot 和 Junit

】Maven依赖于SpringBoot和Junit【英文标题】:MavendependancywithspringbootandJunit【发布时间】:2016-07-1618:12:50【问题描述】:我正在做一个基于spring-boot1.2.5的项目。当我使用maven安装脚本执行测试时,它们会成功通过。但是当我尝试在ecl... 查看详情

使用 Spring Boot 和 JUnit5 在 Intellij 中终止所有测试

】使用SpringBoot和JUnit5在Intellij中终止所有测试【英文标题】:AlltestsgetterminatedinIntellijwithSpringBootandJUnit5【发布时间】:2020-09-1921:45:29【问题描述】:我试图在我的SpringBoot应用程序中使用JUnit5编写一个简单的测试,但我注意到我... 查看详情

如何在 Junit5 / spring boot 中命令执行控制器测试类?

】如何在Junit5/springboot中命令执行控制器测试类?【英文标题】:HowtoorderexecutionofcontrollertestclassesinJunit5/springboot?【发布时间】:2021-05-0806:43:54【问题描述】:在我的实体中,我有双向的一对多关系,我想用mock.mvc编写集成测试。... 查看详情

JUnit 在带有 @Autowired 注释的 Spring Boot 中不起作用

】JUnit在带有@Autowired注释的SpringBoot中不起作用【英文标题】:JUnitnotworkinginSpringBootwith@Autowiredannotation【发布时间】:2018-12-3002:11:12【问题描述】:我有一个SpringBoot应用程序,我正在其中创建RESTWeb服务使用MVC模式。我有一个控制... 查看详情

如何使用 JUnit 测试 Spring Boot aspectj 方法?

】如何使用JUnit测试SpringBootaspectj方法?【英文标题】:HowtotestanSpringBootaspectmethodwithJUnit?【发布时间】:2021-12-2620:59:41【问题描述】:我使用Springboot,我想通过JUnit测试我的新自定义注解。我在importData方法上的@CronLogger自定义注... 查看详情

JUnit get() 方法在 Spring Boot 中不起作用

】JUnitget()方法在SpringBoot中不起作用【英文标题】:JUnitget()methodnotworkinginspringboot【发布时间】:2021-03-0501:36:29【问题描述】:我正在尝试在SpringBoot中使用Junit测试作为练习,但似乎eclipse或IntelliJIDEA似乎无法识别连接测试方法中... 查看详情

用于 Spring Boot 休息控制器的 Junit

...tRestController【发布时间】:2021-05-1914:46:48【问题描述】:如何在SpringBoot中为下面的RestController编写有意义的Junit@GetMapping("/api")publicStringm2(Stringprocess)if(process.equalsIgnoreCase("Y"))j 查看详情

正确配置 Spring Boot 2 和 JUnit 5

】正确配置SpringBoot2和JUnit5【英文标题】:ProperconfigurationofSpringBoot2andJUnit5【发布时间】:2018-08-0716:12:04【问题描述】:使用SpringBoot2.0.0.RC2。我写了一个配置类:@Configuration@ConditionalOnProperty("launchdarkly.sdkKey")publicclassLDClientConfigur 查看详情

java - 如何使用SpringJUnit4TestRunner在junit测试中隐藏spring boot banner.txt?

】java-如何使用SpringJUnit4TestRunner在junit测试中隐藏springbootbanner.txt?【英文标题】:Howtohidespringbootbanner.txtinjunittestwithSpringJUnit4TestRunner?【发布时间】:2016-01-3015:23:09【问题描述】:当我配置SpringBoot应用程序时,我可以通过静态mai... 查看详情

使用 JUnit 5 的 spring-boot-starter-test

...:从2.0.6开始使用spring-boot-starter-test会引入JUnit4依赖项。如何使用spring-boot-starter-test(通过Gradle),但使用JUnit5,而不引入JUnit4依赖项?如果有 查看详情

Spring Boot JUnit 和 @TestPropertySource 使用多个属性文件

】SpringBootJUnit和@TestPropertySource使用多个属性文件【英文标题】:SpringBootJUnitand@TestPropertySourceusingmultiplepropertyfiles【发布时间】:2019-03-2008:02:55【问题描述】:SpringBoot2.0.3.RELEASE有多个属性文件要处理..application.properties和application-... 查看详情