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

如何在Mockito的when()与verify()中处理Sort.by参数?

问题场景

我有一段Controller中的方法代码:

@RequestMapping("addWorkout")
public String addWorkout(ModelMap modelmap, HttpSession session) {
    LOGGER.info("Inside addWorkout,Start");
    int userId=(int)session.getAttribute("userId");
    // modelmap.addAttribute("userId",id);

    List<Workout> workoutList = workoutRepo.findByUserId(userId,Sort.by(new Sort.Order(Direction.DESC, "date"), new Sort.Order(Direction.DESC, "startTime")));
    modelmap.addAttribute("workoutList", workoutList);
    modelmap.addAttribute("exerciseList", exerciseRepo.findAll());
    LOGGER.info("Inside addWorkout,end");
    return "AddWorkout";
}

现在要为其中的workoutRepo.findByUserId(userId,Sort.by(...))编写Mockito的when()调用,我已经写了部分测试代码,但不知道如何处理Sort参数:

@Test
void addWorkoutTest() {
    int userId = 1;

    List<Workout> mockWorkoutList = new ArrayList<>();
    List<Exercise> mockExerciseList = new ArrayList<>();
    when(exerciseRepo.findAll()).thenReturn(mockExerciseList);
    when(session.getAttribute("userId")).thenReturn(userId);
    // 待补全的代码:
    // when(workoutRepo.findByUserId(anyInt(),     ) ).thenReturn(mockWorkoutList);
    String result = workoutController.addWorkout(modelMap, session);
    verify(exerciseRepo, times(1)).findAll();
    verify(session, times(1)).getAttribute("userId");
    verify(modelMap, times(1)).addAttribute("workoutList", mockWorkoutList);
    verify(modelMap, times(1)).addAttribute("exerciseList", mockExerciseList);
    assertNotNull(result);
}

我想了解在when()调用中处理Sort参数的不同方式,需要具体示例来学习。


解决方案

下面提供几种处理Sort参数的常见方式,从简单到精确:

1. 任意匹配(最简便)

如果不需要验证Sort的具体规则,只是想让方法返回模拟数据,可以用any()或any(Sort.class)直接匹配任意Sort对象:

when(workoutRepo.findByUserId(anyInt(), any(Sort.class))).thenReturn(mockWorkoutList);

或者更简洁的写法:

when(workoutRepo.findByUserId(anyInt(), any())).thenReturn(mockWorkoutList);

这种方式适合只关注方法调用是否发生,不关心Sort具体参数的场景。

2. 精确匹配Sort对象

先构造和Controller中完全一致的Sort对象,然后用它作为匹配条件:

// 构造和Controller中相同的Sort
Sort expectedSort = Sort.by(
    new Sort.Order(Direction.DESC, "date"),
    new Sort.Order(Direction.DESC, "startTime")
);
// 精确匹配
when(workoutRepo.findByUserId(eq(userId), eq(expectedSort))).thenReturn(mockWorkoutList);

Sort类的equals()方法会按内部排序规则做比较,只要排序字段和方向一致,就能匹配成功。

3. 自定义匹配器验证Sort规则

如果需要验证Sort的具体排序规则(比如字段、方向),但不想完全复制Sort对象,可以用Mockito的argThat()结合自定义断言:

when(workoutRepo.findByUserId(anyInt(), argThat(sort -> {
    // 验证排序规则:第一个是date降序,第二个是startTime降序
    List<Sort.Order> orders = sort.toList();
    return orders.size() == 2
            && orders.get(0).getProperty().equals("date")
            && orders.get(0).getDirection() == Direction.DESC
            && orders.get(1).getProperty().equals("startTime")
            && orders.get(1).getDirection() == Direction.DESC;
}))).thenReturn(mockWorkoutList);

这种方式可以灵活验证Sort的细节,适合需要确保排序逻辑正确的场景。

4. 使用Hamcrest匹配器(可选)

如果项目中引入了Hamcrest,也可以用它的匹配器组合验证:

import org.hamcrest.Matchers;

when(workoutRepo.findByUserId(anyInt(), Matchers.allOf(
    Matchers.hasProperty("orders", Matchers.hasSize(2)),
    Matchers.hasProperty("orders", Matchers.contains(
        Matchers.allOf(
            Matchers.hasProperty("property", Matchers.equalTo("date")),
            Matchers.hasProperty("direction", Matchers.equalTo(Direction.DESC))
        ),
        Matchers.allOf(
            Matchers.hasProperty("property", Matchers.equalTo("startTime")),
            Matchers.hasProperty("direction", Matchers.equalTo(Direction.DESC))
        )
    ))
))).thenReturn(mockWorkoutList);

这种方式可读性稍差,但适合习惯Hamcrest语法的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 15:47:04