Spring Boot 3.0中ObservationRegistry的JUnit测试是否有替代实现方案?
替代测试实现方法探讨
背景
在Spring Boot 3.0环境下,针对控制器中使用Observation的/getAllRecommendedMovies接口,已编写了基于静态Mock的JUnit测试,现探讨其他更优雅的替代测试方案。
现有代码
控制器中的GET方法
@GetMapping("/getAllRecommendedMovies") public ResponseEntity<BookMyTicket> getAllRecommendedMovies( @RequestParam(value = "theatreName", required = false) String theatreName, @RequestParam(value = "pincode", required = false) Integer pincode, HttpServletRequest request) { return Observation.createNotStarted( request.getRequestURI().substring(1), observationRegistry ).observe(() -> new ResponseEntity<>( theatreManagementService.getAllRecommendedMovies(theatreName, pincode), HttpStatus.OK )); }
现有JUnit测试代码
@Test public void getAllRecommendedMovies() throws Exception { try (MockedStatic<Observation> utilities = Mockito.mockStatic(Observation.class)) { utilities.when( () -> Observation.createNotStarted(Mockito.eq("getAllRecommendedMovies"), Mockito.any()) ).thenReturn(Observation.NOOP); } mockMvc.perform(get("/getAllRecommendedMovies")).andExpect(status().isOk()); }
替代测试方案
方案1:注入No-op类型的ObservationRegistry
通过向测试环境注入无操作(No-op)的ObservationRegistry,避免静态Mock,更贴合Spring依赖注入的设计理念。
测试代码示例:
@Autowired private MockMvc mockMvc; @Autowired private ObservationRegistry observationRegistry; @BeforeEach void setUp() { // 配置ObservationRegistry使用无操作处理器 observationRegistry.observationConfig().observationHandler(new NoOpObservationHandler()); } @Test public void getAllRecommendedMovies() throws Exception { mockMvc.perform(get("/getAllRecommendedMovies")) .andExpect(status().isOk()); }
也可以直接在测试类中提供No-op的ObservationRegistry Bean:
@Configuration static class TestConfig { @Bean public ObservationRegistry observationRegistry() { return ObservationRegistry.noOp(); } }
方案2:重构代码抽离Observation创建逻辑
将Observation的创建逻辑封装到独立组件中,测试时Mock该组件而非静态方法,提升代码可测试性。
步骤1:创建Observation辅助组件
@Component public class ObservationHelper { private final ObservationRegistry observationRegistry; public ObservationHelper(ObservationRegistry observationRegistry) { this.observationRegistry = observationRegistry; } public Observation createObservation(String name) { return Observation.createNotStarted(name, observationRegistry); } }
步骤2:修改控制器注入辅助组件
@Autowired private ObservationHelper observationHelper; @GetMapping("/getAllRecommendedMovies") public ResponseEntity<BookMyTicket> getAllRecommendedMovies( @RequestParam(value = "theatreName", required = false) String theatreName, @RequestParam(value = "pincode", required = false) Integer pincode, HttpServletRequest request) { return observationHelper.createObservation(request.getRequestURI().substring(1)) .observe(() -> new ResponseEntity<>( theatreManagementService.getAllRecommendedMovies(theatreName, pincode), HttpStatus.OK )); }
步骤3:编写测试Mock辅助组件
@Autowired private MockMvc mockMvc; @MockBean private ObservationHelper observationHelper; @Test public void getAllRecommendedMovies() throws Exception { when(observationHelper.createObservation("getAllRecommendedMovies")) .thenReturn(Observation.NOOP); mockMvc.perform(get("/getAllRecommendedMovies")) .andExpect(status().isOk()); }
方案3:利用Spring Boot Test的观测自动配置
Spring Boot Test提供@AutoConfigureObservations注解,可简化测试环境下的观测配置,无需手动Mock静态方法或组件。
测试代码示例:
@SpringBootTest @AutoConfigureMockMvc @AutoConfigureObservations public class TheatreManagementControllerTest { @Autowired private MockMvc mockMvc; @Test public void getAllRecommendedMovies() throws Exception { mockMvc.perform(get("/getAllRecommendedMovies")) .andExpect(status().isOk()); } }
该注解会自动配置测试用的Observation环境,默认不产生实际观测数据,适合单元测试场景。
内容的提问来源于stack exchange,提问作者Joseph24x7
相关产品推荐
相关产品推荐

