Issue
I wanted to test with Mockito that a method was not called with a specific parameter type with this simplified test:
@Test
public void testEm() {
EntityManager emMock = Mockito.mock(EntityManager.class);
emMock.persist("test");
Mockito.verify(emMock, Mockito.never()).persist(Matchers.any(Integer.class));
}
Surprisingly this test failed with the following output:
org.mockito.exceptions.verification.NeverWantedButInvoked:
entityManager.persist(<any>);
Never wanted here:
-> at com.sg.EmTest.testEm(EmTest.java:21)
But invoked here:
-> at com.sg.EmTest.testEm(EmTest.java:19)
I expected this test to fail only when the persist method is called with an Integer parameter, but it fails with String as well.
Why doesn't it work and how could I test it?
Thank You.
Solution
The persist()
method takes an argument as Object
and when you select any(Integer.class)
will be converted to any object, so it will fail because you call it using String
.
The best method here to specify the argument using eq()
, like this
Mockito.verify(emMock, Mockito.never()).persist(Matchers.eq(Integer.valueOf(1)));
Or use ArgumentCaptor
to capture the arguments and assert them
@Test
public void testEm() {
// Arrange
EntityManager emMock = Mockito.mock(EntityManager.class);
ArgumentCaptor<Object> captor = ArgumentCaptor.forClass(Object.class);
// Act
emMock.persist("test");
// Assert
verify(emMock).persit(captor.catpure());
Object val = captor.getValue();
Assert....
}
Answered By - heaprc
Answer Checked By - Clifford M. (JavaFixing Volunteer)