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)
{
.....
}
}
@Mock is used to create mocks that are needed to support the testing of the class to be tested. @InjectMocks is used to create class instances that need to be tested in the test class. Annotated class to be tested dependencies with @Mock annotation.
thenReturn or doReturn() are used to specify a value to be returned upon method invocation. //”do something when this mock's method is called with the following arguments” doReturn("a").
Mockito was released as an open-source testing framework under the MIT (Massachusetts Institute of Technology) License. It internally uses the Java Reflection API to generate mock objects for a specific interface. Mock objects are referred to as the dummy or proxy objects used for actual implementations.
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.
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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With