Mockito InvalidUseOfMatchersException异常排查:因Sonar规则添加eq()匹配器引发的参数匹配问题
Let's break down what's causing this error and fix it step by step. That exception pops up due to two key misuses of Mockito matchers in your code:
1. You're using a matcher in thenReturn (which isn't allowed!)
Look at this line in your test:
when(cardBlockService.sendBlockRequest(cardReplaceRqst)).thenReturn(new ResponseEntity<>(any(), HttpStatus.OK));
The any() here is the culprit. Mockito matchers like any() or eq() only belong in the parameter list of the method you're stubbing (inside the when() call). You can't use them to construct the object you're returning with thenReturn.
Instead, you need to pass an actual instance (or a mocked instance) of whatever type the ResponseEntity expects. For example, if your block request returns a specific response body type, you could do:
// Mock a valid response body (replace with your actual type) YourBlockResponseBodyType mockBody = Mockito.mock(YourBlockResponseBodyType.class); when(cardBlockService.sendBlockRequest(cardReplaceRqst)) .thenReturn(new ResponseEntity<>(mockBody, HttpStatus.OK));
2. Align with Sonar's rule (you're halfway there!)
Sonar told you to add eq() to one parameter, which follows Mockito's core rule: if you use any matcher for a method's parameters, all parameters must use matchers. Your second stub already does this correctly:
when(cardReplaceService.replaceCard(ArgumentMatchers.eq(cardReplaceRqst), any(CardType.class))) .thenReturn(mockCardReplaceResponse());
Both parameters use matchers (eq() and any()), so that part is good. If you want to fully align your first stub with Sonar's suggestion, you can add eq() for the request parameter there too:
when(cardBlockService.sendBlockRequest(eq(cardReplaceRqst))) .thenReturn(new ResponseEntity<>(mockBody, HttpStatus.OK));
Full Corrected Test Code
Here's how your fixed test should look:
@Test @DisplayName("Success scenario for Card Replace for Lost") void testcardReplaceLostSuccess() throws Exception { final CardReplaceRqst cardReplaceRqst = mockCardReplaceRequest("Lost"); // Create/mock a valid response body for the block request YourBlockResponseBodyType mockBlockResponseBody = Mockito.mock(YourBlockResponseBodyType.class); when(cardBlockService.sendBlockRequest(eq(cardReplaceRqst))) .thenReturn(new ResponseEntity<>(mockBlockResponseBody, HttpStatus.OK)); when(cardReplaceService.replaceCard(ArgumentMatchers.eq(cardReplaceRqst), any(CardType.class))) .thenReturn(mockCardReplaceResponse()); mockMvc .perform(MockMvcRequestBuilders.post(REPLACE_REQUEST_URL) .contentType(MediaType.APPLICATION_JSON_VALUE) .content(TestUtils.toJson(cardReplaceRqst)) .characterEncoding("utf-8")) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(jsonPath("$.successCode").value("Success")); }
Just remember: Matchers are exclusively for stubbing method arguments, not for building return values. Stick to this rule and Mockito will stop throwing this error at you.
内容的提问来源于stack exchange,提问作者Sujan Ponnappa

