Mockito, mock class and real call void Methods - java

as the title suggests, the problem is this: I have the mock of AdesioneMerger and I have to call the real merge method. merge is a void method.
This is wrong:
adesioneMerger = Mockito.spy(AdesioneMerger.class);
Mockito.when(adesioneMerger.merge(
Matchers.any(AdesioneBean.class),
Matchers.any(Adesione.class),
Matchers.any(ServiceResultBean.class))
).ThenCallRealMethod();
what's the error?

For void methods, use the alternative API:
Mockito.doCallRealMethod()
.when(adesioneMerger).merge(
Matchers.any(AdesioneBean.class),
Matchers.any(Adesione.class),
Matchers.any(ServiceResultBean.class));
The problem is that Mockito.when() requires an argument (and there are no void-typed arguments in Java). The alternative API works around this by calling when() on the mock type and the actual method to mock is called on the return value of when(...).
See also this answer: How to make mock to void methods with mockito

try this way:
doCallRealMethod().when(adesioneMerger).merge(
Matchers.any(AdesioneBean.class),
Matchers.any(Adesione.class),
Matchers.any(ServiceResultBean.class);

Related

How to define AnswersWithDelay for a void returning method

So, I want to mimic in Mockito a method that is making a network call and is waiting for it to complete before returning. I found this nice answer here: https://stackoverflow.com/a/50530261/4433222 that suggests using AnswersWithDelay.
Issue is though that I struggle to define a method's behavior for a method that returns void. AnswersWithDelays constructor requires a parameter of Answer<Object> type, and I wasn't able to find how to set it as void. Any clues?
First of all, AnswersWithDelay is an internal class of Mockito. So you should not use it directly. Instances of this class are supposed to be created by using the factory methods in the public AdditionalAnswers class.
So all you need is
doAnswer(AdditionalAnswers.answersWithDelay(delay, invocation -> null)).when(mockObject).doSomething();
Based on this answer, with a draft test class.
#ExtendWith(SpringExtension.class)
public class MockDelayVoidTest {
#MockBean
private Object myMock;
void test(){
Mockito.doAnswer(AdditionalAnswers.answersWithDelay(1000, invocationOnMock -> {
//here you can customize the behavior of your mock method
return null;}))
.when(myMock).toString();
}
}
Another way may be,
Mockito.doAnswer(invocation -> {
TimeUnit.SECONDS.sleep(5);
return null;
}).when(mock).doSomething();

PowerMockito returns null when mock constrtuctor is defined for any arguments

I've been trying to figure out what's the deal with PowerMockito's constructor mocking. My code is similar to the following:
public void testConstruction() {
whenNew(Account.class).withAnyArguments().thenReturn(mock(Account.class));
assertNotNull(new Account("name")); //fails
}
I'm not really sure where else to look for to find what's causing this issue. With the above stubbing code, PowerMockito will only return the object created by mock(Account.class) when I call the constructor with no arguments; it's acting as if I stubbed it using withNoArguments(). I'm sure that my test class is set up correctly because the following code passes:
public void testConstruction() {
whenNew(Account.class).withArguments("name").thenReturn(mock(Account.class));
assertNotNull(new Account("name")); //passes
}
I ran into similar issue. withAnyArguments doesn't behave as expected if the class being mocked has more than one constructor. In my case the class mocked with whenNew had 2 constructors and I would always get null when new instance of this class was created. https://github.com/powermock/powermock/issues/891 gave some hint and I switched to using withArguments.

Using PowerMockito to mock method with void return-type: "invalid void parameter"

I am having some trouble trying to unit test java code that at some point calls native methods. Basically, I am trying to use PowerMockito to mock the class that will eventually call native. I was able to mock non-void methods just fine, but I keep getting compilation errors when I try to mock a method of void return type. Here is an example of the code I'm trying to test:
public class ClassThatCallsNative {
void initObject(ByteBuffer param1, int param2) {
//calls native
}
int getId(int param1) {
//calls native
}
}
I have this code in my test class:
PowerMockito.when(mClassThatCallsNative.getId(Mockit.anyInt())).thenReturn(0);
This line of code compiles just fine, however the following line is where I get compilation error:
PowerMockito.when(mClassThatCallsNative.initObject(Mockit.any(ByteBuffer.class), anyInt())).doNothing();
The error message just says invalid void parameter and points to .initObject.
Any idea what I am doing wrong?
Since you are trying to mock method which returns void, you simply can't call it inside when() method. This is because PowerMockito.when() methods expects T methodCall but got void, this is the reason for compilation failure.
Instead you should use this syntax:
PowerMockito.doNothing().when(mClassThatCallsNative).initObject(any(ByteBuffer.class), anyInt())
any() and anyInt() methods are part of Mockito class.
For void methods, you need to use below one
PowerMockito.doNothing().when(mClassThatCallsNative.initObject(Mockit.any(ByteBuffer.class), anyInt()))
Figured out what the problem was, at last. Turns out I needed the instance of ClassThatCallsNative in order to mock it's methods. What was happening before is that the object was being initialized inside a constructor call, but when I created another constructor that takes ClassThatCallsNative as a parameter, and set my instance to that instead, everything worked fine.
Thank you anyways!

Powermockito doNothing for method with arguments

I've developed an application in Java and I'm trying to create unit tests using Powermockito (I should add that I'm new to unit testing).
I have a class called Resource which has a static method called readResources:
public static void readResources(ResourcesElement resourcesElement);
ResourcesElement is also coded by me.
In testing, I want to create my own Resource, so I want the above method to do nothing.
I tried using this code:
PowerMockito.spy(Resource.class);
PowerMockito.doNothing().when(Resource.class, "readResources", Matchers.any(ResourcesElement.class));
The unit test throws an exception:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at org.powermock.api.mockito.internal.PowerMockitoCore.doAnswer(PowerMockitoCore.java:36)
Powermockito also suggest that I should use thenReturn or thenThrow after when, but it seems that the method 'when' returns void when it is called after doNothing (which is logical).
If I try:
PowerMockito.when(Resource.class, "readResources", Matchers.any(ResourcesElement.class)).....
doNothing is not an option after when.
I managed to make methods without arguments to do nothing, using the 2 arguments version of the method. For example:
PowerMockito.doNothing().when(Moduler.class, "startProcessing");
This works (startProcessing doesn't take any arguments).
But how can I make methods that do take arguments to do nothing with Powermockito?
You can find a fully functional example below. Since you didn't post the complete example, I can only assume that you did not annotate the test class with #RunWith or #PrepareForTest because the rest seems fine.
#RunWith(PowerMockRunner.class)
#PrepareForTest({Resource.class})
public class MockingTest{
#Test
public void shouldMockVoidStaticMethod() throws Exception {
PowerMockito.spy(Resource.class);
PowerMockito.doNothing().when(Resource.class, "readResources", Mockito.any(String.class));
//no exception heeeeere!
Resource.readResources("whatever");
PowerMockito.verifyStatic();
Resource.readResources("whatever");
}
}
class Resource {
public static void readResources(String someArgument) {
throw new UnsupportedOperationException("meh!");
}
}
Why go through so much trouble just so that your method does not do anything. Just calling PowerMockito.mockStatic(Resource.class) should replace all static methods in your class with default stubs which basically mean they do nothing.
Unless you do want to change the behavior of your method to actually do something just calling PowerMockito.mockStatic(Resource.class) should suffice. Ofcourse this also means all static methods in the class are stubbed which you need to consider.
If doNothing() isn't working you can hack it a bit using the PowerMockito.doAnswer(). This lets you mock into void methods that are supposed to do something, like setting values, etc. If doNothing() doesn't work, using a blank doAnswer() should work fine.
Example:
PowerMockito.doAnswer(new org.mockito.stubbing.Answer<Object>() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return null; //does nothing
}
}).when(mockObject).methodYouWantToDoNothing(args);
Maybe i can't undestand your question, but i believe it's necessary specify what must do
the method, so if you don't specify thenReturn or thenThrow or whatever powerMockito doesn't know what have to do when read your real code, for example:
REAL CODE:
IPager pag;
IPagerData<List<IDeute>> dpag;
pag = new PagerImpl();
pag.setFiles(nombrefilesPaginador);
pag.setInici(1);
dpag = gptService.obtenirDeutes(idSubjecte, idEns, tipusDeute, periode, pag);
Testing real code by mockito:
IPager pag = new PagerImpl();
pag.setInici(1);
pag.setFiles(0);
when(serveiGpt.obtenirDeutes(eq(331225L),
eq(IConstantsIdentificadors.ID_ENS_BASE),
Matchers.any(ETipusDeute.class),
Matchers.any(EPeriodeDeute.class),
eq(pag)))
.thenThrow(new NullPointerException(" Null!"));
If haven't specify the return my test will be fail.
I hope it helps.
I tried doNothing with different variations but nothing worked except the below solution.
#Before
public void setUp(){
obj = new ClassObj (parameters);
//parameters should also include the class obj for which void method is available
}

Mockito: Trying to spy on method is calling the original method

I'm using Mockito 1.9.0. I want mock the behaviour for a single method of a class in a JUnit test, so I have
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
The problem is, in the second line, myClassSpy.method1() is actually getting called, resulting in an exception. The only reason I'm using mocks is so that later, whenever myClassSpy.method1() is called, the real method won't be called and the myResults object will be returned.
MyClass is an interface and myInstance is an implementation of that, if that matters.
What do I need to do to correct this spying behaviour?
Let me quote the official documentation:
Important gotcha on spying real objects!
Sometimes it's impossible to use when(Object) for stubbing spies. Example:
List list = new LinkedList();
List spy = spy(list);
// Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
// You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
In your case it goes something like:
doReturn(resultsIWant).when(myClassSpy).method1();
In my case, using Mockito 2.0, I had to change all the any() parameters to nullable() in order to stub the real call.
My case was different from the accepted answer. I was trying to mock a package-private method for an instance that did not live in that package
package common;
public class AnimalĀ {
void packageProtected();
}
package instances;
class Dog extends Animal { }
and the test classes
package common;
public abstract class AnimalTest<T extends Animal> {
#Before
setup(){
doNothing().when(getInstance()).packageProtected();
}
abstract T getInstance();
}
package instances;
class DogTest extends AnimalTest<Dog> {
Dog getInstance(){
return spy(new Dog());
}
#Test
public void myTest(){}
}
The compilation is correct, but when it tries to setup the test, it invokes the real method instead.
Declaring the method protected or public fixes the issue, tho it's not a clean solution.
The answer by Tomasz Nurkiewicz appears not to tell the whole story!
NB Mockito version: 1.10.19.
I am very much a Mockito newb, so can't explain the following behaviour: if there's an expert out there who can improve this answer, please feel free.
The method in question here, getContentStringValue, is NOT final and NOT static.
This line does call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), isA( ScoreDoc.class ));
This line does not call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), any( ScoreDoc.class ));
For reasons which I can't answer, using isA() causes the intended (?) "do not call method" behaviour of doReturn to fail.
Let's look at the method signatures involved here: they are both static methods of Matchers. Both are said by the Javadoc to return null, which is a little difficult to get your head around in itself. Presumably the Class object passed as the parameter is examined but the result either never calculated or discarded. Given that null can stand for any class and that you are hoping for the mocked method not to be called, couldn't the signatures of isA( ... ) and any( ... ) just return null rather than a generic parameter* <T>?
Anyway:
public static <T> T isA(java.lang.Class<T> clazz)
public static <T> T any(java.lang.Class<T> clazz)
The API documentation does not give any clue about this. It also seems to say the need for such "do not call method" behaviour is "very rare". Personally I use this technique all the time: typically I find that mocking involves a few lines which "set the scene" ... followed by calling a method which then "plays out" the scene in the mock context which you have staged... and while you are setting up the scenery and the props the last thing you want is for the actors to enter stage left and start acting their hearts out...
But this is way beyond my pay grade... I invite explanations from any passing Mockito high priests...
* is "generic parameter" the right term?
One more possible scenario which may causing issues with spies is when you're testing spring beans (with spring test framework) or some other framework that is proxing your objects during test.
Example
#Autowired
private MonitoringDocumentsRepository repository
void test(){
repository = Mockito.spy(repository)
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
In above code both Spring and Mockito will try to proxy your MonitoringDocumentsRepository object, but Spring will be first, which will cause real call of findMonitoringDocuments method. If we debug our code just after putting a spy on repository object it will look like this inside debugger:
repository = MonitoringDocumentsRepository$$EnhancerBySpringCGLIB$$MockitoMock$
#SpyBean to the rescue
If instead #Autowired annotation we use #SpyBean annotation, we will solve above problem, the SpyBean annotation will also inject repository object but it will be firstly proxied by Mockito and will look like this inside debugger
repository = MonitoringDocumentsRepository$$MockitoMock$$EnhancerBySpringCGLIB$
and here is the code:
#SpyBean
private MonitoringDocumentsRepository repository
void test(){
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
Important gotcha on spying real objects
When stubbing a method using spies , please use doReturn() family of methods.
when(Object) would result in calling the actual method that can throw exceptions.
List spy = spy(new LinkedList());
//Incorrect , spy.get() will throw IndexOutOfBoundsException
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
I've found yet another reason for spy to call the original method.
Someone had the idea to mock a final class, and found about MockMaker:
As this works differently to our current mechanism and this one has different limitations and as we want to gather experience and user feedback, this feature had to be explicitly activated to be available ; it can be done via the mockito extension mechanism by creating the file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing a single line: mock-maker-inline
Source: https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
After I merged and brought that file to my machine, my tests failed.
I just had to remove the line (or the file), and spy() worked.
One way to make sure a method from a class is not called is to override the method with a dummy.
WebFormCreatorActivity activity = spy(new WebFormCreatorActivity(clientFactory) {//spy(new WebFormCreatorActivity(clientFactory));
#Override
public void select(TreeItem i) {
log.debug("SELECT");
};
});
As mentioned in some of the comments, my method was "static" (though being called on by an instance of the class)
public class A {
static void myMethod() {...}
}
A instance = spy(new A());
verify(instance).myMethod(); // still calls the original method because it's static
Work around was make an instance method or upgrade Mockito to a newer version with some config: https://stackoverflow.com/a/62860455/32453
Bit late to the party but above solutions did not work for me , so sharing my 0.02$
Mokcito version: 1.10.19
MyClass.java
private int handleAction(List<String> argList, String action)
Test.java
MyClass spy = PowerMockito.spy(new MyClass());
Following did NOT work for me (actual method was being called):
1.
doReturn(0).when(spy , "handleAction", ListUtils.EMPTY_LIST, new String());
2.
doReturn(0).when(spy , "handleAction", any(), anyString());
3.
doReturn(0).when(spy , "handleAction", null, null);
Following WORKED:
doReturn(0).when(spy , "handleAction", any(List.class), anyString());

Categories

Resources