Trying to mock a method with int parameter but Mockito fails - mockito

I want to simulate the response of the following method:
public JobResult getJobResult(String jobId, int pageSize, String cursor)
The following way:
when(analyticsApi.getJobResult(any(), any(), any())).thenReturn(jobResult);
But Mockito fails with the following error:
java.lang.NullPointerException: Cannot invoke
"java.lang.Integer.intValue()" because the return value of
"org.mockito.ArgumentMatchers.any()" is null

Turns out you cannot put any() on int parameters, so you have to mock it the following way:
when(analyticsApi.getJobResult(any(), anyInt(), any())).thenReturn(jobResult);

Related

Issue with Mockito.Any for overloaded methods

I have two methods in my Java class as below
Method 1:
public ResponseEntity<T> callMethod(String param1,Map<String, String> param2, Object param3,HttpMethod param4,Class<T> param5)
Method 2
public ResponseEntity<T> callMethod(Map<String, String> param1, Object param2,
HttpMethod param3, Map<String, ?> param4,
final Class<T> param5) {
I have written a unit test case where when i try to call the method as below
callMethod(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
eq(ServiceResponse.class))).thenReturn(responseEntity)
it fails with the below error
reference to callMethod is ambiguous
both method callMethod
(java.util.Map<java.lang.String,java.lang.String>,B,org.springframework.http.HttpMethod,java.util.Map<java.lang.String,?>,java.lang.Class)
and method
callMethod(java.lang.String,java.util.Map<java.lang.String,java.lang.String>,B,org.springframework.http.HttpMethod,java.lang.Class)
match
How can this be resolved. There are many unit test cases and i want to fix the class than the unit test cases. Is there a way?
Yes, you can put types in the any() like any(MyClass.class) there are also some built in ones. If you want to call your first method you can use the anyString() and anyMap() ones.
callMethod(Mockito.anyString(), Mockito.anyMap(), Mockito.any(), Mockito.any(HttpMethod.class), eq(ServiceResponse.class))).thenReturn(responseEntity)

how to match the String... use Mockito and PowerMock

I am studying Mockito and PowerMock recently.
I ran into the following problem
//This method belongs to the Messages class
public static String get(Locale locale, String key, String... args) {
return MessageSupplier.getMessage(locale, key, args);
}
//the new class
#RunWith(PowerMockRunner.class)
#PowerMockIgnore( {"javax.management.*"})
#PrepareForTest({Messages.class, LocaleContextHolder.class})
public class DiscreT {
#Test
public void foo() {
PowerMockito.mockStatic(LocaleContextHolder.class);
when(LocaleContextHolder.getLocale()).thenReturn(Locale.ENGLISH);
PowerMockito.mockStatic(Messages.class);
when(Messages.get(Mockito.any(Locale.class),Mockito.anyString(), Mockito.any(String[].class)))
.thenReturn("123156458");
System.out.print(Messages.get(LocaleContextHolder.getLocale(), "p1"));
System.out.print(Messages.get(LocaleContextHolder.getLocale(), "p1", "p2"));
}
}
the result : null 123156458
why? and how to match the String...
In your first System.out.print statement, you use 2 arguments for the Messages.get method. This is one of the method's overloads that you have not mocked. That's why it returns null. Note that object mocks that have not had their behavior mocked will return null by default.
You would have to mock the Messages.get(Locale, String) method as well if you want it to work
when(Messages.get(Mockito.any(Locale.class),Mockito.anyString()))
.thenReturn("123156458");
Remember, the fact that you have mocked the method that takes the most arguments doesn't mean Mockito understands and mocks the rest of the overloads! You have to mock them as well.
There is no way to mock a method once and automatically mock all of its overloads as far as I know however, there is a way to create a mock object and configure a default response for all of its methods. Check out http://www.baeldung.com/mockito-mock-methods#answer

Passing file instance as parameter to a method with Object argument

I have a setResultValue method which accepts Object as argument
public class CommandResult {
// other methods
public void setResultValue(Object resultValue) {
this.resultValue = resultValue;
}
And am trying to pass a java.io.File instance file to this method as below
new CommandResult.setResultFile(file);
And am seeing the below error
groovy.lang.MissingMethodException: No signature of method: com.dc.core.behavior.command.model.impl.CommandResult.setResultFile() is applicable for argument types: (java.io.File) values:
Possible solutions: setResultValue(java.lang.Object), getResultValue()
Isnt the method setResultFile supposed to accept file since Object is the super class of all instances?
Your method signature is setResultValue. You call setResultFile.

Mock Void type in Mockito

Say Foo is the class we mock and Foo has a method named Foo.bar() which returns type Void (not void). How can we use Mockito to mock this method?
Not sure whether returning null in this case would be the best solution.
Because Void is final and not instantiable, there is no instance you could ever return. In production, that method can only return null (if it returns at all), and that should hold true in your tests as well.
Note that Mockito will return null by default for methods that return Object instances other than collections and primitive wrappers, so you should only need to stub a method that returns Void if you need to override a spied method:
// Spy would have thrown exception
// or changed object state
doReturn(null).when(yourSpy).someMethodThatReturnsVoid();
Or throw an exception:
// Throw instead of returning null by default
when(yourMock.someMethodThatReturnsVoid()).thenThrow(new RuntimeException());
Or react with an Answer:
when(yourMock.someMethodThatReturnsVoid()).thenAnswer(new Answer<Void>() {
#Override public void answer(InvocationOnMock invocation) {
// perform some action here
return null;
}
}

PowerMockito can't seem to match and overloaded method

I can't seem to overcome this problem. I'm trying to mock an overloaded method that takes 1 argument
class ClassWithOverloadedMethod {
private boolean isValid(ClassA a){
return true;
}
private boolean isValid(ClassB B){
return false;
}
}
Mock setup
ClassWithOverloadedMethod uut = PowerMockito.spy(new ClassWithOverloadedMethod());
PowerMockito.doReturn(true).when(uut, "isValid", Matchers.isA(ClassB.class));
but PowerMockito keeps returning this error
java.lang.NullPointerException
at java.lang.Class.isAssignableFrom(Native Method)
at org.powermock.reflect.internal.WhiteboxImpl.checkIfParameterTypesAreSame(WhiteboxImpl.java:2432)
at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1934)
at org.powermock.reflect.internal.WhiteboxImpl.getBestMethodCandidate(WhiteboxImpl.java:1025)
at org.powermock.reflect.internal.WhiteboxImpl.findMethodOrThrowException(WhiteboxImpl.java:948)
at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:882)
at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:713)
at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:401)
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:93)
I'm using PowerMockito 1.5 with Mockito 1.9.5
Try using one of the when() methods that accepts a Method object. You can use Whitebox to retrieve the method instance you want by specifying the parameter type which should get around your current issue.
So something like
Method m = Whitebox.getMethod(ClassWithOverloadedMethod.class, ClassB.class);
PowerMockito.doReturn(true).when(uut, m).withArguments(Matchers.any(ClassB.class));
See Also
http://powermock.googlecode.com/svn/docs/powermock-1.5.1/apidocs/org/powermock/api/mockito/expectation/PowerMockitoStubber.html#when(java.lang.Class,%20java.lang.reflect.Method)
http://powermock.googlecode.com/svn/docs/powermock-1.5.1/apidocs/org/powermock/reflect/Whitebox.html#getMethod(java.lang.Class,%20java.lang.Class...)

Resources