Ishan Tiwary
Ishan Tiwary

Reputation: 1008

Mockito.when giving InvalidUseOfMatchersException: Misplaced or misused argument matcher detected here

Following is the Test Class

@RunWith(MockitoJUnitRunner.class)
public class AuditServiceClientTest {

private MockMvc mockMvc;

@Mock
private RestTemplate restTemplate;

@Mock
AuditServiceClient auditServiceClient;

@Mock
ICommonDataService iCommonDataService;

private AuditServiceResponse auditServiceResponse;

private AuditServiceLog auditServiceLog;

private HttpEntity<AuditServiceLog> request;

@Before
public void setUp() throws Exception {

    MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
    headers.add("X-AGS-Client-Name", "test");
    headers.add("X-AGS-Group-Name", "test");
    headers.add("Content-Type", "application/json");
    auditServiceClient = new AuditServiceClientImpl();
    iCommonDataService = new CommonDataService();
    auditServiceLog = new AuditServiceLog();
    request = new HttpEntity<AuditServiceLog>(auditServiceLog, headers);
    auditServiceResponse = new AuditServiceResponse();
    auditServiceResponse.setStatus(String.valueOf(200));
    auditServiceResponse.setTimestamp("1990-01-01 00:00:01");
    auditServiceResponse.setDescription("Description");
    Mockito.when(restTemplate.postForObject(Mockito.anyString(), any(HttpEntity.class), ArgumentMatchers.eq(AuditServiceResponse.class)))
            .thenReturn(auditServiceResponse);
    String a = "test";
    ArrayList<Integer> mockedList = new ArrayList<Integer>();
    Mockito.when(iCommonDataService.getEnvValue(Mockito.anyInt(), Mockito.anyInt(), Mockito.anyString()))
            .thenReturn(a);
}

@Test
public void postTest() {

    AuditServiceResponse response = null;
    try {

        response = auditServiceClient.post("endpoint", auditServiceLog, true);
    } catch (Exception e) {
        e.printStackTrace();
    }
    Assert.assertTrue(Integer.parseInt(response.getStatus() )== 200);
}
}

I am getting

InvalidUseOfMatchersException: Misplaced or misused argument matcher detected here

in the setUp() method on the following line:

 Mockito.when(iCommonDataService.getEnvValue(Mockito.anyInt(), Mockito.anyInt(), Mockito.anyString()))
        .thenReturn(a);

Following is the error:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Misplaced or misused argument matcher detected here:

-> at com.auditService.test.AuditServiceClientTest.setUp(AuditServiceClientTest.java:72)

You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:

when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo"))

This message may appear after an NullPointerException if the last matcher is returning an object like any() but the stubbed method signature expect a primitive argument, in this case, use primitive alternatives.

when(mock.get(any())); // bad use, will raise NPE
when(mock.get(anyInt())); // correct usage use

Also, this error might show up because you use argument matchers with methods that cannot be mocked. Following methods cannot be stubbed/verified: final/private/equals()/hashCode(). Mocking methods declared on non-public parent classes is not supported.

There are a lot of articles on this error around but none of them worked for me. Is there any issue with Mockito.anyInt() because Mockito.anyString() is being used in the previous line and that works fine. Any help is appreciated.

Upvotes: 1

Views: 17498

Answers (2)

ARK
ARK

Reputation: 1

I used @RunWith(SpringRunner.class)instead of @RunWith(MockitoJUnitRunner.class) which helps to resolve this issue.

Upvotes: 0

Pavel Smirnov
Pavel Smirnov

Reputation: 4799

Look carefully at your test code:

iCommonDataService = new CommonDataService();
    ...
Mockito.when(iCommonDataService.getEnvValue(Mockito.anyInt(), Mockito.anyInt(), Mockito.anyString()))
            .thenReturn(a);

You're mocking a method of an object wich is not a mock, that's the cause of the exception.

Since you already have a mock of this class declared wih @Mock annotation, you can simply remove this line iCommonDataService = new CommonDataService();. Another way could be providing a mock manually using Mockito.mock(CommonDataService.class).

But, if you want to mock a method of the original object, you should use Mockito.spy() instead.

Upvotes: 9

Related Questions