如何在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
相关产品推荐
相关产品推荐

