Mockito Exception - when() requires an argument which has to be a method call on a mock

JavaControllerMockitoSpring Test

Java Problem Overview


I have a very simple test case that is using Mockito and Spring Test framework. When I do

when(pcUserService.read("1")).thenReturn(pcUser);

I get this exception.

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.

	at com.project.cleaner.controller.test.PcUserControllerTest.shouldGetPcUser(PcUserControllerTest.java:93)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)

I have tried with different methods but keep on getting this error message. I am using Spring 3.1.0.RELEASE with Mockito. Please share and guide me in the right direction.

Java Solutions


Solution 1 - Java

You need to create a MOCK of pcUserService first, and then use that mock.

PcUserService mock = org.mockito.Mockito.mock(PcUserService.class);
when(mock.read("1")).thenReturn(pcUser);

Solution 2 - Java

In case others hit this issue....

It could also be the case that the method you are trying to mock out,pcUserService.read, is declared as a final method. From what I've noticed this appears to cause issues with Mockito.

Solution 3 - Java

If you use Kotlin, you should know that methods are final by default. So write open fun instead of fun. Thanks to @djkelly99 for a tip.

Solution 4 - Java

Another solution to this issue might be that in case of a test class that is using PowerMockRunner, you might have to add the class that you are mocking to the list, in @PrepareForTest annotation.

For instance -

@PrepareForTest({ PcUserService.class })

Solution 5 - Java

In my case it was solved by injecting @MockBean.

For ex.

@MockBean
StateRepository mockStateRepository;

Solution 6 - Java

There's another possible reason for such error - sometimes IDE prefers to statically import Mockito.when() from another package:

import static io.codearte.catchexception.shade.mockito.Mockito.when;

vs

import static org.mockito.Mockito.when; //should normally use this one

The thing is 'when' from io.codearte package is compliant with org.mockito.Mockito.any() on compilation level, but fails during runtime with that exact same error message.

Solution 7 - Java

I had the same issue, the method that I was trying to mock it was a final method. I removed the modifier and it worked fine.

Solution 8 - Java

For the help of others who stuck with the same problem;

The method you are trying to mock , pcUserService.read, is declared as a final method. Static methods appears to cause issues with Mockito.

Solution 9 - Java

Basically You need to use the PowerMockito.mockStatic to enable static mocking for all static methods of a class. This means make it possible to stub them using the when-thenReturn syntax. For example: PowerMockito.mockStatic(TestClass.class); when(TestClass.getString()).thenReturn("HelloWorld!"); Note: you have to add @PrepareForTest({ TestClass.class }) to your unit test class.

Solution 10 - Java

If you get this exception when using MockedStatic or Mockito.mockStatic, it can also mean that you are mixing matchers and literals in the call to the static method.

Try changing any mixes like YourClass.staticMethod(any(), "literal") to YourClass.staticMethod(any(), eq("literal"))

Solution 11 - Java

If you use KOIN, include in the gradle's dependencies:

dependencies {
    ...
    testImplementation "org.koin:koin-test:2.0.0"
}

Solution 12 - Java

I faced similar issue when mocking static method of anotherClass called inside testing a method of someClass. In that case, we need to add @PrepareForTest({anotherClass.class, someClass.class}) both the class having the static method and caller class.

Solution 13 - Java

When I got this exception, I was using @InjectMocks on the class that I needed to have the @Mock objects injected into (via constructor injection).

AFter much searching, I finally stumbled across this article:

https://mkyong.com/spring-boot/mockito-when-requires-an-argument-which-has-to-be-a-method-call-on-a-mock/

The key part to take away from it is (from the article):

> When Mockito see this @InjectMocks, it doesn’t mock it, it just > creates a normal instance, so the when() will be failed.

So this make this exception message I was getting

> when() requires an argument which has to be 'a method call on a mock'.

make sense now; you aren't using when on an actual mock but an actual instance.

The link also provides the solution to the problem:

> To solve it, annotate @Spy to mock it partially.

On top of @InjectMocks, put @Spy.

As a side note, if you try to make it a Mock by putting @Mock on top of @InjectMocks, you will get exception:

> org.mockito.exceptions.base.MockitoException: This combination of > annotations is not permitted on a single field: @Mock and @InjectMocks

Using @Spy on top of @InjectMocks solved the problem for me.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjsfView Question on Stackoverflow
Solution 1 - JavaRalphView Answer on Stackoverflow
Solution 2 - Javadjkelly99View Answer on Stackoverflow
Solution 3 - JavaCoolMindView Answer on Stackoverflow
Solution 4 - JavaSaranView Answer on Stackoverflow
Solution 5 - JavaNinad PingaleView Answer on Stackoverflow
Solution 6 - JavaMichał 'PuszekSE'View Answer on Stackoverflow
Solution 7 - JavaThomás PreisView Answer on Stackoverflow
Solution 8 - JavapasindupaView Answer on Stackoverflow
Solution 9 - JavaajainView Answer on Stackoverflow
Solution 10 - JavaTom ChamberlainView Answer on Stackoverflow
Solution 11 - JavaJ. SoaresView Answer on Stackoverflow
Solution 12 - JavaDhruvajyoti ChatterjeeView Answer on Stackoverflow
Solution 13 - JavaMike CheelView Answer on Stackoverflow