如何在单个Spring测试用例中覆盖单个application.properties配置属性
解决单个测试用例覆盖Spring Boot配置属性的简洁方案
针对你的需求,最简洁的方式是直接在目标测试方法上使用@TestPropertySource注解(Spring Boot 2.2及以上版本支持方法级别的该注解),无需新增测试类或配置文件,直接覆盖单个测试的属性值:
@Test @TestPropertySource(properties = "app.enableRegistration=false") void cannotRegisterUserWhenRegistrationsAreDisabled() throws Exception { var userToSave = validUserEntity("username", "password"); // 注意:当注册禁用时,控制器不会调用userDetailsServiceImpl.post,所以可以移除下面这句不必要的mock // when(userDetailsServiceImpl.post(userToSave)).thenReturn(savedUser); mvc.perform(post("/api/v1/auth/register/") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsBytes(userToSave))) .andExpect(status().isCreated()) .andExpect(jsonPath("$.status", is("registrations are disabled"))); }
为什么这个方案可行?
@TestPropertySource在方法级别使用时,优先级高于类级别注解、全局application.properties配置,会临时将app.enableRegistration设为false,仅对当前测试方法生效,其他测试方法依然使用全局配置的true值。
可选方案(针对低版本Spring Boot)
如果你的Spring Boot版本低于2.2,不支持方法级别的@TestPropertySource,可以通过MockEnvironment动态修改属性:
@Autowired private Environment environment; @Test void cannotRegisterUserWhenRegistrationsAreDisabled() throws Exception { // 强制转换为MockEnvironment(WebMvcTest环境下默认是MockEnvironment) ((MockEnvironment) environment).setProperty("app.enableRegistration", "false"); var userToSave = validUserEntity("username", "password"); mvc.perform(post("/api/v1/auth/register/") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsBytes(userToSave))) .andExpect(status().isCreated()) .andExpect(jsonPath("$.status", is("registrations are disabled"))); }
测试代码优化建议
你当前的测试中,当注册功能禁用时,控制器逻辑会直接返回"registrations are disabled",不会执行userDetailsServiceImpl.post方法,所以when(userDetailsServiceImpl.post(userToSave)).thenReturn(savedUser)这句mock是多余的,可以移除,让测试逻辑更准确。
内容的提问来源于stack exchange,提问作者sineverba
相关产品推荐
相关产品推荐

