PowerMockito chaining doesn't work reliably for Spied class - mockito

I've a test where the System Under Test calls a static method. The static method belongs to a final class(it is a utility class).
The test code is as follows:
#Test
public void test() throws Exception {
SUT sut = PowerMockito.spy(new SUT());
PowerMockito.spy(A.class);
stub(method(A.class, "methodOne")).toReturn("CONST_STRING");
PowerMockito.when(A.methodTwo(anyLong(), anyLong()))
.thenReturn(false, true, false); //The problem!
sut.method("arg1");
assertThat(//some assert);
}
I get intermittent errors on the below line. It passes sometimes & sometimes, it fails.
PowerMockito.when(A.methodTwo(anyLong(), anyLong()))
.thenReturn(false, true, false);
When it fails, below is the error that it displays:
[junit] Misplaced argument matcher detected here:
[junit]
[junit] -> at com.project.SUTTest.test(SUTTest.java:40)
[junit] -> at com.project.SUTTest.test(SUTTest.java:40)
[junit]
[junit] You cannot use argument matchers outside of verification or stubbing.
[junit] Examples of correct usage of argument matchers:
[junit] when(mock.get(anyInt())).thenReturn(null);
[junit] doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
[junit] verify(mock).someMethod(contains("foo"))
[junit]
[junit] Also, this error might show up because you use argument matchers with methods that cannot be mocked.
[junit] Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
[junit] Mocking methods declared on non-public parent classes is not supported.
[junit]
[junit] org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
[junit] Misplaced argument matcher detected here:
[junit]
[junit] -> at com.project.SUTTest.test(SUTTest.java:40)
[junit] -> at com.project.SUTTest.test(SUTTest.java:40)
[junit]
[junit] You cannot use argument matchers outside of verification or stubbing.
[junit] Examples of correct usage of argument matchers:
[junit] when(mock.get(anyInt())).thenReturn(null);
[junit] doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
[junit] verify(mock).someMethod(contains("foo"))
[junit]
[junit] Also, this error might show up because you use argument matchers with methods that cannot be mocked.
[junit] Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
[junit] Mocking methods declared on non-public parent classes is not supported.
My version of PowerMockito - 1.6.3
What is happening? Why is the failure intermittent? What is causing this unreliable behaviour?
PowerMockito chaining doesn't work reliably for Spied class

Related

PowerMockito Argument Matching failure

I am trying to use PowerMockito to mock a private class like this:
PowerMockito.when(spyClass, "privateMethod", anyString()).thenReturn(returnList);
I have these two annotations above the test method:
#Test
#PrepareForTest(CartItemRepository.class)
And these above the class:
#ExtendWith(MockitoExtension.class)
#RunWith(PowerMockRunner.class)
There are no previous method calls (stubbed or otherwise) in the test method that could be interfering.
But, I am getting an error related to incorrect use of argument matchers.
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.
I am using the when method of PowerMockito (and not regular Mockito) but the 2nd error paragraph makes it seem like mocking private methods is still not possible.
I'm not sure what I'm doing wrong here.

Trying to define a Mockito-stub executes the mocked method. Why?

We are trying to define a UnitTest where we mock an object which I here called x for simplicity:
...
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import org.kubek2k.springockito.annotations.SpringockitoContextLoader;
import org.kubek2k.springockito.annotations.WrapWithSpy;
...
#ContextConfiguration(
loader = SpringockitoContextLoader.class,
inheritLocations = true)
public class SyncServiceIntegrationTest extends AbstractIntegrationTest {
#Autowired
#WrapWithSpy
private EventDrivenIssueDeliveryConfirmer x;
...
#Before
public void setUp() {
...
doNothing().when(x).foobar(any(Event.class));
}
...
i.e. we want our UT (not shown here) to later NOT call the method foobar on that object x.
Strange enough we get an NPE during initialization of this UT-class. The NPE is thrown by method foobar(), when the passed argument is null.
As turned out this call with argument null happens in the line doNothing()... in the setup-method which in our understanding is supposed to just define the mock-object's stubbing. But instead it evaluates the any(Event.class)-expression which apparently yields null and with that result it then calls the foobar(...)-method on x which causes the NPE.
Besides the NullPointerException we also get an error message from Mockito:
java.lang.NullPointerException: null
... <stack trace omitted for brevity>
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here:
-> at ch.sst.integration.SyncServiceIntegrationTest .setUp(SyncServiceIntegrationTest.java:69)
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
... <examples omitted for brevity>
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at ch.sst.integration.SyncServiceIntegrationTest .setUp(SyncServiceIntegrationTest.java:69)
...
Why is that so??? Why is our stubbing considered "unfinished"? What are we missing here?
Later addition:
The issue seems to have to do with the fact that class
EventDrivenIssueDeliveryConfirmer is marked with #Transactional. Removing/commenting that lets the UT succeed. But of course that's no workaround - we need that annotation.
At least this provides a hint in which direction to search. The wrapping caused by #Transactional and the wrapping done by Mockito seem to step on each other's foot here.
I have the same issue but with a totally different setup: kotlin, mockito and, of course, mockito-kotlin.
I comment on this issue because maybe somebody will come to this question with the kotlin mockito problem in the future? I sure did. Anyhow.
When not declaring a method as open in kotlin it's compiled as a final method which can't be mocked by mockito-kotlin. As a result the method gets executed which to me is kind of weird but that's what it does. It's mentioned in the mockito-kotlin github issues under https://github.com/mockito/mockito-kotlin/issues/314

Invalid use of argument matchers! (Mockito)

I got an error when I was using Mockito.
I use the matchers for all parameters, but an error has occurred.

Dexguard implemenation

Hi getting the below error with dexguard and I have also excluded the android.support.v7.app in rule
java.lang.VerifyError: Verifier rejected class android.support.v7.app.AppCompatDelegate: void android.support.v7.app.AppCompatDelegate.() failed to verify: void android.support.v7.app.AppCompatDelegate.(): [0x0] Constructor returning without calling superclass constructor (declaration of 'android.support.v7.app.AppCompatDelegate' appears in /data/app/com.intradiem.agentmobile-nzRaODeKWvj81AKePijb-A==/base.apk)
at android.support.v7.app.AppCompatDelegate.setCompatVectorFromResourcesEnabled(:525)
at com.intradiem.agentmobile.IntradiemApplication.(:27)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newApplication(Instrumentation.java:1102)
at android.app.Instrumentation.newApplication(Instrumentation.java:1087)
at android.app.LoadedApk.makeApplication(LoadedApk.java:983)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5715)
This sounds like a problem with the -assumenosideeffects rule.
Ensure that you do not use wildcards in combination with this rule, like that:
-assumenosideeffects class XXX {
*;
}
This will also remove calls to the superclass constructors as you experience it.

Mockito verify method is called ignoring parameter

I have a DAO method I want to verify is called inside Service
send(User user, Properties prop)
I can verify using a protected method in service, but I think it should be private
verify(dao).send(user, service.getProp())
I tried in different ways to define accepting any properties as:
verify(dao).send(user, any(Properties.class)); // or any()
verify(dao).send(user, Matchers.isA(Properties.class)));
But all failed with invalid arguments
FAILED: testService
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
2 matchers expected, 1 recorded:
-> at com.package.TestService.testService(TestService.java:330)
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
For more info see javadoc for Matchers class.
As the exception details explain, you're not allowed to mix raw values (user) with matchers (any(...)).
Instead, use matchers for all arguments using the eq(...) matcher:
verify(dao).send(eq(user), any());

Resources