Mockito: Wanted but not invoked

匿名 (未验证) 提交于 2019-12-03 09:05:37

问题:

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)    {     .....    } } 

回答1:

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)); 


回答2:

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.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!