We have Jenkins shared library project with some unit-tests that utilize Mockito. After an upgrade of Jenkins-core from version 2.325 to 2.326 tests start failing on the following line:
class DSLMock {
DSLMock() {
this.mock = mock(DSL.class)
-> when(mock.invokeMethod(eq("error"), any())).then(new Answer<String>() {
@Override
String answer(InvocationOnMock invocationOnMock) throws Throwable {
throw new AbortException((String) invocationOnMock.getArguments()[1][0])
}
})
...
with error:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here:
-> at com.devops.jenkins.testing.DSLMock.<init>(DSLMock.groovy:66)
-> at com.devops.jenkins.testing.DSLMock.<init>(DSLMock.groovy:66)
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"))
This message may appear after an NullPointerException if the last matcher is returning an object
like any() but the stubbed method signature expect a primitive argument, in this case,
use primitive alternatives.
when(mock.get(any())); // bad use, will raise NPE
when(mock.get(anyInt())); // correct usage use
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.
I've tried to replace any() with methods like anyString() and just value like "" but still got same error. Also I've tried different stub syntax like
doAnswer(new Answer...).when(mock).invokeMethod(eq("error"), any())
In changelog https://www.jenkins.io/changelog-old/#v2.326 I see Groovy patch version has been upgraded:
- Upgrade Groovy from 2.4.12 to 2.4.21
I wonder if that would cause the issue. Other dependencies versions are not changed:
<groovy.version>2.4.12</groovy.version>
<junit-jupiter.version>5.8.1</junit-jupiter.version>
<mockito.core.version>3.3.3</mockito.core.version>
CodePudding user response:
I tried to reproduce your error locally but faced a compilation error on line: throw new AbortException((String) invocationOnMock.getArguments()[1][0])
. Could you maybe try the following:
when(mock.invokeMethod(eq("error"), any(String[].class))).then(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocationOnMock) throws Throwable {
String[] array = (String[]) invocationOnMock.getArguments()[1];
throw new AbortException((String) array[0]);
}
});
CodePudding user response:
Have you tried to spy DSL class instead?
this.mock = spy(DSL.class)