You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对使用Stream流的Java业务方法进行单元测试?

测试前置准备

首先你需要准备基础测试依赖,推荐使用JUnit 5 + Mockito组合,用来模拟依赖方法的返回值,避免测试受外部真实数据影响。如果你的项目用到JavaFX的ObservableList,可额外引入TestFX依赖解决JavaFX运行时测试问题。
你需要模拟的依赖方法包括服务类中的getAppointmentsForSpecificDoctor()、getAllAppointments(),单元测试时只验证你写的Stream逻辑正确性,不需要调用这两个方法的真实实现。

getAppointmentsForToday() 测试用例

该方法逻辑为:过滤指定医生的所有预约,返回日期为当天的预约列表,可覆盖3个测试场景:

  • 场景1:存在当天预约,返回正确过滤结果

构造3条测试预约数据,2条日期为当天、1条为其他日期,模拟getAppointmentsForSpecificDoctor()返回这3条数据,断言返回的列表长度为2,且所有返回预约的日期均为当天。

  • 场景2:无当天预约,返回空列表

构造的所有预约日期均不为当天,模拟依赖方法返回后,断言结果为空列表。

  • 场景3:无任何预约数据,返回空列表

模拟getAppointmentsForSpecificDoctor()返回空列表,断言结果为空。

getScheduledTime(User pickedDoctor, LocalDate pickedDate) 测试用例

该方法逻辑为:先过滤出姓名匹配的医生的所有预约,再过滤出指定日期的预约,最后提取时间字段返回,可覆盖4个测试场景:

  • 场景1:存在对应医生对应日期的预约,返回正确时间列表

构造2个不同姓名医生的预约数据,其中目标医生有3条预约,2条属于指定日期,时间分别为09:00、14:00,模拟getAllAppointments()返回所有构造数据,传入目标医生和指定日期调用方法,断言返回的列表长度为2,且包含两个目标时间。

  • 场景2:对应医生无指定日期的预约,返回空列表

构造的目标医生预约均不在指定日期,断言返回结果为空。

  • 场景3:无对应姓名的医生的预约,返回空列表

构造的所有预约中没有对应姓名的医生数据,断言返回结果为空。

  • 场景4:无任何预约数据,返回空列表

模拟getAllAppointments()返回空列表,断言结果为空。

测试示例代码(JUnit5 + Mockito)
@ExtendWith(MockitoExtension.class)
public class AppointmentServiceTest {
    // 用@Spy注解测试真实服务类,仅模拟依赖的外部方法
    @Spy
    private AppointmentService appointmentService;

    @Test
    void getAppointmentsForToday_HasTodayAppointments_ReturnsCorrectList() {
        // 固定测试时间,避免跨天测试失败
        LocalDate testToday = LocalDate.of(2024, 5, 20);
        try (MockedStatic<LocalDate> mockedLocalDate = Mockito.mockStatic(LocalDate.class)) {
            mockedLocalDate.when(LocalDate::now).thenReturn(testToday);
            // 构造测试数据
            Appointment app1 = new Appointment(testToday, new Doctor("张", "三"));
            Appointment app2 = new Appointment(testToday, new Doctor("张", "三"));
            Appointment app3 = new Appointment(testToday.plusDays(1), new Doctor("张", "三"));
            // 模拟依赖方法返回
            doReturn(List.of(app1, app2, app3)).when(appointmentService).getAppointmentsForSpecificDoctor();
            
            // 调用测试方法
            List<Appointment> result = appointmentService.getAppointmentsForToday();
            
            // 断言结果
            assertEquals(2, result.size());
            assertTrue(result.stream().allMatch(app -> app.getDate().equals(testToday)));
        }
    }
}
测试注意事项
  • 时间稳定性:所有涉及LocalDate.now()的测试,都建议固定返回值,不要用系统当前时间,避免跨天执行测试时结果不一致。
  • 业务边界校验:第二个方法用医生firstName做匹配规则,如果业务允许医生重名,当前逻辑会返回所有同名医生的预约,你可根据业务需求补充对应测试用例,验证逻辑是否符合预期。
  • JavaFX依赖处理:如果测试环境没有启动JavaFX上下文,FXCollections.observableArrayList()可能抛出异常,可引入TestFX框架解决,也可以直接把返回的ObservableList转成普通List做断言,不需要依赖JavaFX运行时特性。

内容的提问来源于stack exchange,提问作者sooope

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 22:54:03