如何在Spring同一单元测试类的不同方法中配置不同属性
如何用不同配置属性集测试@ConfigurationProperties类?
你想要在单个测试类中,针对标注了@ConfigurationProperties的MyConfig类,使用不同配置属性集测试其初始化逻辑,替代示例中虚构的@UseProperties注解,以下是几种可行的实现方式:
方案1:结合@TestPropertySource与@DirtiesContext
利用Spring Boot的@TestPropertySource注解为每个测试方法指定专属属性,配合@DirtiesContext确保每个测试方法运行在独立的上下文环境中,避免属性污染。
@SpringBootTest(classes = { MyConfig.class }) @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) // 每个测试后销毁上下文 class MyConfigTest { @Autowired MyConfig myConfig; @Test @TestPropertySource(properties = "my-config.prop1=foo") void test1() { assertThat(myConfig.getProp1()).isEqualTo("foo"); // 执行你的业务断言逻辑 } @Test @TestPropertySource(properties = "my-config.prop1=bar") void test2() { assertThat(myConfig.getProp1()).isEqualTo("bar"); // 执行你的业务断言逻辑 } @Test @TestPropertySource(properties = "my-config.prop1=foobar") void test3() { assertThat(myConfig.getProp1()).isEqualTo("foobar"); // 执行你的业务断言逻辑 } }
注意:这种方式每次测试都会重建Spring上下文,适合逻辑简单的测试场景,若测试方法较多会影响执行速度。
方案2:使用TestPropertyValues动态设置属性(更高效)
通过TestPropertyValues类在测试方法内部动态覆盖属性,无需重建整个上下文,性能更优。
@SpringBootTest(classes = { MyConfig.class }) class MyConfigTest { @Autowired ApplicationContext context; @Autowired MyConfig myConfig; @Test void test1() { TestPropertyValues.of("my-config.prop1=foo") .applyTo(context.getEnvironment()); // 销毁原实例并重新获取,确保新属性生效 context.getBeanFactory().destroyBean(myConfig); MyConfig refreshedConfig = context.getBean(MyConfig.class); assertThat(refreshedConfig.getProp1()).isEqualTo("foo"); // 执行你的业务断言逻辑 } @Test void test2() { TestPropertyValues.of("my-config.prop1=bar") .applyTo(context.getEnvironment()); context.getBeanFactory().destroyBean(myConfig); MyConfig refreshedConfig = context.getBean(MyConfig.class); assertThat(refreshedConfig.getProp1()).isEqualTo("bar"); // 执行你的业务断言逻辑 } }
方案3:参数化测试(推荐,减少重复代码)
利用JUnit 5的参数化测试特性,把不同属性值作为参数传入,一次性完成多组测试,代码更简洁。
@SpringBootTest(classes = { MyConfig.class }) class MyConfigTest { @Autowired ApplicationContext context; @ParameterizedTest @ValueSource(strings = {"foo", "bar", "foobar"}) void testWithDifferentProperties(String propValue) { // 覆盖配置属性 TestPropertyValues.of("my-config.prop1=" + propValue) .applyTo(context.getEnvironment()); // 刷新配置实例 context.getBeanFactory().destroyBean(context.getBean(MyConfig.class)); MyConfig myConfig = context.getBean(MyConfig.class); assertThat(myConfig.getProp1()).isEqualTo(propValue); // 根据属性值执行对应业务断言 if ("foo".equals(propValue)) { // test1专属断言逻辑 } else if ("bar".equals(propValue)) { // test2专属断言逻辑 } else if ("foobar".equals(propValue)) { // test3专属断言逻辑 } } }
优势:只需编写一次核心测试逻辑,自动遍历所有测试参数,既减少重复代码,又保证测试执行效率。
内容的提问来源于stack exchange,提问作者Daniele Repici
相关产品推荐
相关产品推荐

