powerMock does not throw exception, it actually goes into the method - mockito

This is my code snippet:
PowerMockito
.doThrow(new Exception())
.when((spy),
method(Mocked.class, "privateMethod", MyParameter.class))
.withArguments(parameter);
actualObject.publicMethod();
Here, I have a public method which calls privateMethod. I have a Mocked class which I have declared as:
#InjectMocks
Mocked mocked;
But by doing so, Mockito is not throwing any exception when it gets into the mocked class, and when private method is encountered it does not throw an exception.
In when(), should there always be a spy object, but the problem here is JUnit actually runs the private method, which I don't want. I need to simply throw an exception whenever this private method is called, so I can to cover all the catch blocks (which is not happening).

Add #PrepareForTest for the class.

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

getting org.mockito.exceptions.misusing.InvalidUseOfMatchersException in a seemingly right code

I have a when call like this :
#Mock
private MyEventFactory myEventFactory;
#Mock
private MyEvent myEvent;
when(myEventFactory.createMyEvent(anyObject(),anyObject(),anyObject(),anyObject(),anyObject(),anyObject(),anyObject(),anyObject(),anyObject(),anyObject(),anyObject())).thenReturn(myEvent);
However I get an exception
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced argument matcher detected here:
You cannot use argument matchers outside of verification or stubbing.
MyEventFactory is an interface
What could be the issue here ?
Have you initialized the mocks? It would help to see the full code posted, but I suspect you need to call something like
MockitoAnnotations.initMocks(this);
before you run your when statement. This article shows an example: https://howtodoinjava.com/mockito/mockito-mock-initmocks/

how not invoke specific method on spring batch

Is there a way with mockito to test my batch and tell to not invoke specific method that the process call MyService.class, inside that service i got some business logic in a specific method that i don't want him to invoke is that possible? I was sure that doing the doReturn will ignore my method (the method is public) but still get call.
#Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
#Autowired
private MyRepo myRepoRepository;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testJob() throws Exception {
doReturn(true).when(spy(MyService.class)).validationETPer(any(Object.class), anyChar());
doReturn(true).when(spy(MyService.class)).validationMP(any(Object.class),anyChar());
JobExecution execution = jobLauncherTestUtils.launchJob();
assertEquals(execution.getStepExecutions().size(), 1);
for (StepExecution stepExecution : execution.getStepExecutions()) {
assertEquals(3, stepExecution.getReadCount());
assertEquals(3, stepExecution.getWriteCount());
}
assertEquals(ExitStatus.COMPLETED.getExitCode(), execution.getExitStatus().getExitCode());
assertEquals(2, myRepoRepository.count());
}
This line does not what you believe it does:
doReturn(true).when(spy(MyService.class)).validationETPer(any(Object.class), anyChar());
spy(MyService.class) creates a new instance of MyService and spies on it. Of course, since you never use that instance, it's completely useless. There is an instance that is spied on, but you didn't store it anywhere, you didn't put it anywhere and so nobody will ever use it.
That line does not spy on every MyService in existence, as you seem to believe, it creates one concrete instance of MyService and spies on that. Obviously, that's not what you want here - you want to spy on the instance that is actually used in your code.
What you probably wanted to do, is more something like this...
MyService mySpy = spy(MyService.class);
doReturn(true).when(mySpy).validationETPer(any(Object.class), anyChar());
jobLauncherTestUtils.setMyService( mySpy ); // or something like that
// and NOW you can test
It's hard to go deeper in the details without knowing how the MyService is used in your actual code. Personally, I would suggest starting with unit tests without spring and using spring test only for higher level tests.

How to execute original method in Mockito after Answer on Spy object

I would like to know is the thing in the description possible and how to do it.
I know you can call original method and then do the Answer like this:
when(presenter, "myMethod").doAnswer(<CUSTOMANSWER>)
but I would like to order them differently, first do CUSTOMANSWER and then call the original method.
For followers, it's actually possible to doAnswer and callRealMethod at the same time...
doAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
invocationOnMock.callRealMethod(); // this one
return null;
}
}).when(subject).method(...);
You won't ever see when(...).doAnswer() in Mockito. Instead, you'll see either of the following, which includes the "call real method" behavior you're describing. As usual with Mockito stubbing, Mockito will select the most recent chain of calls that matches the method call and argument values in the invocation, and do each action in the chain once until the final action (which it will do for all calls afterwards.
// Normal Mockito syntax assuming "myMethod" is accessible. See caveat below.
when(presenter.myMethod()).thenAnswer(customAnswer).thenCallRealMethod();
// ...or...
doAnswer(customAnswer).doCallRealMethod().when(presenter).myMethod();
That said, there's a deficiency in the PowerMockito API that makes this difficult, because after the first doAnswer call all subsequent calls you get a normal Mockito Stubber instance rather than a PowerMockitoStubber instance. The bug 599 was misinterpreted, so for the time being you'll still have to make the cast yourself.
((PowerMockitoStubber) doAnswer(customAnswer).doCallRealMethod())
.when(presenter, "myMethod");

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!

Resources