2

I have mock method for a rest call.

public void createRestClientMock() {
        org.mockito.Mockito.when(
                restClient.sendResponse(org.mockito.Matchers.anyString(),
                        org.mockito.Matchers.anyString())).thenAnswer(
                new Answer<Object>() {
                    public Object answer(InvocationOnMock invocation) {
                        Object[] args = invocation.getArguments();
                        actualResponse = args[1].toString();
                        LOG.debug(actualResponse);
                        return null;
                    }
                });
    }

The real method is getting mocked as expected and everything is working fine when i run the junit from eclipse.

But when i try to run the junit from Jenkins using maven build, i am getting the below error:-

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Misplaced argument matcher detected here:

-> at uk.co.common.Test.createRestClientMock(Test.java:166)

You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
    when(mock.get(anyInt())).thenReturn(null);
    doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
    verify(mock).someMethod(contains("foo"))

Also, this error might show up because you use argument matchers with methods that cannot be mocked.
Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
Mocking methods declared on non-public parent classes is not supported.

adding the dependencies

<dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>2.0.13-beta</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-core</artifactId>
            <version>1.3</version>
            <scope>test</scope>
        </dependency>
Manu
  • 1,379
  • 6
  • 24
  • 53
  • My first impulse is that there is a dependency problem when running from Jenkins. Are you certain that both the IDE and Jenkins are using precisely the same Mockito and JUnit JARs? – Tim Biegeleisen Jan 10 '16 at 09:07
  • Eclipse and Jemkins the application is getting build using same Maven. The dependencies are same as the same pom.xml used for building. – Manu Jan 10 '16 at 09:12
  • Can you execute from the command line and see if you get the same error? – horatius Jan 10 '16 at 09:13
  • I am getting the same error as running from jekins while running from Maven command line. Anything i am doing wrong in setting the mock. Not having any clue on why its working while executing the junit from eclipse directly – Manu Jan 10 '16 at 10:08
  • Try to remove the Maven local repo in your Jenkins server and rebuild from scratch. Do the same on your computer. – Tunaki Jan 10 '16 at 10:50
  • 1
    The _restClient_ object is a mock object? The _sendResponse_ method is final or private? – Alejandro Goñi Jan 10 '16 at 17:31
  • What was the fix? – Govind Madhu Feb 10 '21 at 11:56

2 Answers2

1

I was experiencing the very same issue and it turned out to be because the maven-surefire-plugin was attempting to use the JUnit3 runner instead of JUnit4, causing the @RunWith(MockitoJUnitRunner.class) annotation to be ignored. There are several potential causes, such as:

  • having both JUnit3 and JUnit4 in the classpath.

  • using a different than the one present in your classpath.

in my case, I was uplifting an existing project and replaced junit:junit-dep with junit:junit without realizing my surefire configuration in the pom had junit:junit-dep. Eclipse ignores anything in the POM and will create a JUnit4 configuration by default, so all tests were passing when running with Run As... JUnit test.

cleberz
  • 601
  • 7
  • 11
-1

Your method looks correct, and can be run in isolation correctly. That means that your error is probably in a different method run as part of the same Maven suite.

Mockito matchers are not purely functional: Behind the scenes there's a ThreadLocal stack of matchers saved for the next stubbing or verification call. Mockito matcher calls add to this stack and return dummy values. However, Mockito can't police this stack very carefully, because it can't analyze or anticipate whether a matcher call is used correctly or incorrectly until the end of the test, at which point it does't have the control it needs to throw an exception. This means that Matchers are particularly subject to test pollution when running a series of Mockito-based tests in the same JVM.

When running your test alone, or using a different suite runner (Maven vs Eclipse), your test works. Unlucky for you, Maven orders your tests so the broken test precedes the test you posted above. Note that the "broken test" still passes; it just leaves the Matcher stack in a bad state, which causes your correct test to fail.


To diagnose your problem, use MockitoJUnitRule to initialize your tests. It will automatically handle @Mock/@Spy/@Captor initialization (replacing MockitoAnnotations.initMocks(this)) and, importantly, it will call Mockito.validateMockitoUsage() at the end of each test. validateMockitoUsage throws an exception if the Matcher stack is empty or if any stubbing or verification call is incomplete; with any luck, the broken test will fail, ensuring that your correct test above passes.

(If you can't use MockitoJUnitRule, fall back to the JUnit4 runner MockitoJUnitRunner, which does the same as MockitoJUnitRule but doesn't work as well with other runners or rules. Of course, you can also call validateMockitoUsage directly, which may come in handy if you're on JUnit3 or you need to identify where within a method you misuse matchers.)

If you find your matcher misuse, and want to understand it better, that might be a good subject for another SO question.

Community
  • 1
  • 1
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251