Service 層常見的 save*、update* 等方法返回 void,無法像有返回值的方法那樣直接斷言結果。測試重點在於 驗證方法內部邏輯是否正確執行、參數是否符合預期、依賴的外部調用是否被正確觸發。
@Override
public void updateRuleName(Long ruleId, String newRuleName, Long ucId) {
Assert.notNull(ruleId, "規則ID不能為Null");
Assert.notNull(newRuleName, "規則名稱不能為Null");
Assert.notNull(ucId, "操作人的UCID不能為Null");
String cleanNewRuleName = StringUtils.trim(newRuleName);
if (StringUtils.isBlank(cleanNewRuleName)) {
throw new IllegalArgumentException("新的規則名稱不能為空");
}
// 查詢規則對象
Rule rule = queryRuleById(ruleId);
if (null == rule) {
throw new IllegalDataException("沒有查到該規則");
}
rule.setRuleId(ruleId);
rule.setRuleName(cleanNewRuleName);
rule.setUpdateUcid(ucId);
rule.setUpdateTime(new Date());
ruleDao.updateSelective(rule);
}
@Test
public void testUpdateRuleName() {
Long ruleId = 1L;
String newRuleName = "newRuleName";
Long ucId = 123L;
// 準備 Mock 數據
List<Rule> rules = new ArrayList<>();
Rule rule = new Rule();
rule.setRuleStatus((byte) DBValueSetting.RULE_STATUS_TAKE_EFFECT);
rules.add(rule);
Map<String, Object> params = new HashMap<>();
params.put("ruleId", ruleId);
// Mock 查詢行為
Mockito.when(ruleDao.queryRulesByCondition(params)).thenReturn(rules);
// 核心:使用 doAnswer 攔截 void 方法調用,驗證入參
Mockito.doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) {
// 獲取傳遞給 updateSelective 的 Rule 物件
Rule rule = (Rule) invocation.getArguments()[0];
// 斷言驗證關鍵業務欄位
Assert.assertTrue(rule.getRuleName().equals("newRuleName"));
return null; // void 方法返回 null
}
}).when(ruleDao).updateSelective(Mockito.any(Rule.class));
// 執行被測方法
ruleService.updateRuleName(ruleId, newRuleName, ucId);
}
public interface Answer<T> {
T answer(InvocationOnMock invocation) throws Throwable;
}
ruleService.updateRuleName(...)ruleDao.updateSelective(rule)Answer.answer() 方法,此時可通過 invocation.getArguments() 獲取實際傳入參數若需驗證調用次數:
Mockito.verify(ruleDao, Mockito.times(1)).updateSelective(Mockito.any(Rule.class));
若需捕獲多個參數進行複雜驗證:
ArgumentCaptor<Rule> captor = ArgumentCaptor.forClass(Rule.class); Mockito.verify(ruleDao).updateSelective(captor.capture()); Rule capturedRule = captor.getValue(); // 對 capturedRule 進行任意複雜斷言