I have a following test method:
MyClass myClass= Mockito.mock(MyClass.class); Mockito.when(myClass.methodUsedInMethodBeingTested(Matchers.any(MyTypeParam.class))).thenReturn(Collections.<X, Y> emptyMap()); assertNull(myClass.methodToTest(myObject)); Mockito.verify(myClass).methodUsedInMethodBeingTested(Matchers.any(MyTypeParam.class));
The methodUsedInMethodBeingTested
is a method that I want to mock and return an empty map. But I am getting the failure message saying
Wanted but not invoked myClass.methodUsedInMethodBeingTested()
.
MyClass { public XYZ methodToTest() { .... .... Map<X,Y> mp = methodUsedInMethodBeingTested(myTypeParam); ..... } public Map<X,Y> methodUsedInMethodBeingTested(MyTypeParam myTypeParam) { ..... } }
You're misunderstanding what a mock is. When you're doing
MyClass myClass = Mockito.mock(MyClass.class); // ... assertNull(myClass.methodToTest(myObject));
You're not actually invoking methodToTest
on your real object. You're invoking methodToTest
on the mock, which by default, does nothing and return null
, unless it was stubbed. Quoting from Mockito docs:
By default, for all methods that return value, mock returns null, an empty collection or appropriate primitive/primitive wrapper value (e.g: 0, false, ... for int/Integer, boolean/Boolean, ...).
This explains your subsequent error: the method was really not invoked on the mock.
It seems what you want here is a spy
instead:
You can create spies of real objects. When you use the spy then the real methods are called (unless a method was stubbed).
A note of warning though: since it is the real methods that are getting called, you should not use Mockito.when
but prefer Mockito.doReturn(...).when
, otherwise the method will be called once for real. If you consider the expression:
Mockito.when(myClass.methodUsedInMethodBeingTested(Matchers.any(MyTypeParam.class))).thenReturn(Collections.<X, Y> emptyMap()); ^-----------------------------------^ this will be invoked by Java
the argument of the method when
must be evaluated, but this means the method methodUsedInMethodBeingTested
will be invoked. And since we have a spy, it is the real method that will be invoked. So, instead, use:
MyClass spy = Mockito.spy(new MyClass()); Mockito.doReturn(Collections.<X, Y> emptyMap()).when(spy).methodUsedInMethodBeingTested(Matchers.any(MyTypeParam.class)); assertNull(spy.methodToTest(myObject)); Mockito.verify(spy).methodUsedInMethodBeingTested(Matchers.any(MyTypeParam.class));
You are invoking the methodToTest
on the mock instance. Because you have not configured it otherwise, that just returns null, it doesn't try to invoke any of the actual method's implementation.