PowerMockito Argument Matching failure - mockito

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.

Related

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

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

Mockito.when() not working

I am trying to mock a call to a protected method of one of my classes:
import com.couchbase.client.java.view.Stale; // an enum
import com.google.common.base.Optional;
public class MyClass {
public List<String> myList(Optional<Integer> arg1, Optional<Stale> arg2) {
...
}
}
The mock shall be accomplished in the following way:
// Providing types for any() does not change anything
Mockito.when(myClass.myList(Mockito.any(), Mockito.any()).thenReturn(new ArrayList());
Whenever the previous line is executed the actual myList() method is called with null values for arg1 and arg2. Why is the method called, at all? After all, I am trying to avoid any executing thereof...
As Brice mentioned, if your myList method is final, then Java skips virtual method dispatch and will call the original object (not your mock).
If you are spying on an actual class, it is expected behavior that when will call the actual object as part of the stub: after all, in the expression when(foo.bar()) Java doesn't know anything special about when and assumes that it cares about the return value) of foo.bar(), not the call itself. (I walk through the stubbing process in the "Implementation details" section of my answer here.)
This syntax is better for spies:
doReturn(new ArrayList()).when(myClass).myList(any(), any());
Because this different when method receives an object, Mockito can prepare the object to do nothing during the stubbing, which avoids any spurious calls to your myList method.
Although Jeff's answer did not show a workaround for my problem it pointed me into the right direction.
After changing the mocking behaviour to doReturn... I suddenly got an error message. This message told me that myClass is not a mock which makes sense since you can only mock (or stub?) methods of mocked or spied objects. So as Jeff's answer indicates and is explained in the documentation of mockito I created a partial mock of MyClass with
MyClass myClass = Mockito.spy(new MyClass());
With this partial mock Jeff's approach to method mocking suddenly worked (mine still does not and should therefore be avoided).
So: Thank you, Jeff!

How to return Array of Objects using Powermock and mockito

I have a method which return array of object.
public IConfigurationElement[] getConfigurationElementsFor(String extensionPointId);
I am not sure how can I mock this call using mockito and powermock.
I have tried
mockConfigurationElements = (IConfigurationElement[]) Mockito.anyListOf( IConfigurationElement.class ).toArray();
but this is ending in ClassCastException.
Mocking (stubbing) calls with Mockito is done in a following way (for example):
Mockito.when(mockObject.getConfigurationElementsFor(Mockito.anyString()).thenReturn(new IConfigurationElement[]{})
or
Mockito.doReturn(new IConfigurationElement[]{}).when(mockObject).getConfigurationElementsFor(Mockito.anyString());
Mockito.anyListOf() is a use of a matcher. Matchers are passed instead of real arguments when stubbing meaning that the behavior is to be applied if the method is called with arguments satisfying those matchers.

Is there a Mockito equivalent way to expect constructor invocations like PowerMock.expectNew?

If it doesn't, does it exist on EasyMock?
Thanks.
PowerMock is intended as an extension of both EasyMock and Mockito. From the horse's mouth: "PowerMock is a framework that extend other mock libraries such as EasyMock with more powerful capabilities."
In any case, there is no EasyMock equivalent to expectNew and neither is there one in Mockito, either - that's exactly the hole that PowerMock is trying to fill. That being said, PowerMock is perfectly capable of doing this with Mockito. Here is the sample from the documentation:
How to mock construction of new objects
Use PowerMockito.whenNew, e.g.
whenNew(MyClass.class).withNoArguments().thenThrow(new
IOException("error message"));
Note that you must prepare the class
creating the new instance of MyClass for test, not the MyClass itself.
E.g. if the class doing new MyClass() is called X then you'd have to
do #PrepareForTest(X.class) in order for whenNew to work.
How to verify construction of new objects
Use PowerMockito.verifyNew,
e.g.
verifyNew(MyClass.class).withNoArguments();

Resources