any(object.class) throwing null in mockito - java

I have the following class:
mockStatic(Exception.class);
PowerMockito.doNothing().when(Exception.class);
Exception.throwErrorIfExists(any(Object.class)); // line3
In exception class,method is defined as follows:
static void throwErrorIfExists(def model){
if(model.hasErrors())
throwError(model)
}
The following exception is thrown at line 3: Cannot invoke method hasErrors() on null object
java.lang.NullPointerException: Cannot invoke method hasErrors() on null object
How can any(object.class) be NULL in any circumstances because any simply means return any anything?

I think you are misusing the any() method. This method exists so that you can verify interactions with mocks, e.g. you can say:
// checks yourMethod() was invoked with any argument
verify(mockedObject).yourMethod(any(SomeClass.class));
If you want to call your method with some arbitrary object, you should create the object in your test and pass it in. any() is not a method that just makes objects for you.

You can't invoke ThrowErrorIfExists with a null parameter, as you invoke a method (hasErrors() on it. This has nothing to do with any mocking, but it is just an error in your method.
You use a matcher to call the method
Exception.throwErrorIfExists(any(Object.class));
which is quite strange; matchers are used to configure the behaviour of a mock like
PowerMockito.doNothing().when(Exception.throwErrorIfExists(any(Object.class)));
Then you can call throwErrorIfExists with any object to trigger the "do nothing".

Related

Unable to mock enum static method with null parameter

I am trying to mock a static method of enum which has null value like below
try (MockedStatic<SomEnum> e = Mockito.mockStatic(SomEnum.class)) {
e.when(() -> SomEnum.methodWhichAcceptingNullParam(any())).thenReturn(somValue);
}
here any() is not working... i am not sure I am passing null parameter inside method
methodWhichAcceptingNullParam
I have tried both any and isNull.The fact is SomEnum.methodWhichAcceptingNullParam is always get called however it should not because I provided a mocked value already
any help?
Is your code called with a null or not-null object? This information is missing (at least for me).
Assuming you are calling SomeEnum.methodWhichAcceptingNullParam(null), then you need to use
ArgumentMatchers.isNull()
instead of any().

Spying on instance variable and return the value when instance function get calls

I am trying to mock class instance and then return the mock object when we call the instance function but in result, it makes an actual call to function.
Here is my code:
AuthenticationSessionModel authSessionCookie =
new AuthenticationSessionManager(session)
.getCurrentAuthenticationSession(realm, client, tabId);
and my test code is:
AuthenticationSessionManager spyAuthSessionManager =
Mockito.spy(new AuthenticationSessionManager(session));
doReturn(authenticationSessionModel)
.when(spyAuthSessionManager)
.getCurrentAuthenticationSession(any(), any(), anyString());
It makes an actual call to getCurrentAuthenticationSession() and returns me Null Pointer Exception
In the test, you create a spy, and stub some behaviour.
But you don't use that spy in the code under test.
Instead, in the code under test you create a new AuthenticationSessionManager.
You need to restructure your code and:
create AuthenticationSessionManager outside of object under test.
pass it to object under test. Constructor is the first thing that comes to mind.
With these changes, it becomes trivial to substitute a real AuthenticationSessionManager with a spy in a test.

Java reflection, call method from superClass?

I've seen a lot of examples, and I know what has been discussed.
I do everything right, but I receive an error. Why is that? What am i doing wrong?
Class superClass = rootObject.getSuperclass();
Method addErrorMethod = superClass.getDeclaredMethod("addErrorMessage", ErrorType.class, String.class, String.class, String.class);
_log.info(addErrorMethod.getName());
addErrorMethod.invoke(superClass, ErrorType.FIELD, propertyName, message, "");
I get method, but when you call the invoker. I get the following error.
java.lang.IllegalArgumentException: object is not an instance of declaring class
Thanks.
When you call Method.invoke the first parameter must be either:
when method is non-static instance of the class which contains the method
when method is static null or class itself.
Since you pass the class itself and you got error it suggests that method you are trying to invoke is not static, so you should invoke it like
addErrorMethod.invoke(rootObject, ErrorType.FIELD, propertyName, message, "");
// ^^^^^^^^^^- assuming it is instance on which we want to invoke this method
You did not do everything right:
addErrorMethod.invoke(superClass, ErrorType.FIELD, propertyName, message, "");
should read
addErrorMethod.invoke(rootObject, ErrorType.FIELD, propertyName, message, "");
superClass is an instance of Class, to which has no addErrorMessage() method, as the error message is telling you. The first parameter to the method is a reference to the object that will be used as this within the method.

Use the method parameters of expect in the andReturn

Collection<T_SI_IDABAREME> tSiIdabaremes;
DAO_F_IDA_DESC mockDaoFIdaDesc
prepareExpects(){
expect(mockDaoTSiIdabareme.findByDate(isA(Date.class)))
.andReturn(searchByParameter(tSiIdabaremes, date));
}
Is it possible to use the date that will be passed to the findByDate in the andReturn?
PS: This is a service test class and I'm doing it in a way to bypass the database.
whenever you use expect method like this
Easymock.expect(someMethod(Date.Class)).andReturn(something);
you are instructing compiler to mock all calls to that method whenever ANY object of Date class is passed as parameter,and you will not be able to use that object in return expression.
on the other hand if you have something like this,
Easymock.expect(someMethod(someSpecificDateObject)).andReturn(someSpecificDateObject);
you are instructing the compiler to mock this method call ONLY when a specific object of Date class is passed as parameter(someSpecificDateObject in this case) and you will be able to use this parameter while returning, because you know that method gets mocked only when this object is passed.
You can use second option if it is favourable to you,but with first option what you ask is not possible.
Hope this helps!
Good luck!
Instead of:
expect(mockDaoTSiIdabareme.findByDate(isA(Date.class)))
.andReturn(searchByParameter(tSiIdabaremes, date));
I should have put
expect(mockDaoTSiIdabareme.findByDate(isA(Date.class)))
.andAnswer(new IAnswer<Collection<T_SI_IDABAREME>>() {
public Collection<T_SI_IDABAREME> answer() throws Throwable {
return searchByParameter((Date)getCurrentArguments()[0]);
}
}
);
Which will only look for the return value when the method is being exectued and then we can use getCurrentArguments() to retrieve the arguments passed to the method.
You can find more about this in the EasyMock Documentation.

mockito checking MethodInvocation

I would like to check that method was invoked with particular parameter using mockito.
I my code, everytime when unit.permission().someCommand() is invoked, the intercetor's method invoke will be invoked along with that. invoke method looks like this:
void invoke(MethodInvocation methodInvocation) ..
This is a test, where I check that interceptor's method was invoked.
#Test
public void permission() throws Throwable {
unit.permission().someCommand();
verify(mockedMethodInterceptor, times(1)).invoke(any(MethodInvocation.class));
}
In this test, as you can see, I use any instance of MethodInvocation.
Question:
Is there any way to check to particular MethodInvocation instance to be sure that invoke() method was invoked with right parameter? This invoke method should hold information about someCommand() method..
Yes.
For this simple case, it's probably ok just to use the value itself in the test:
#Test
public void permission() throws Throwable {
MethodInvocation expectedInvocation = makeItHoweverYouDo();
unit.permission().someCommand();
verify(mockedMethodInterceptor, times(1)).invoke(expectedInvocation);
}
Getting that to be the one that's actually called by your code may require that you inject that value somewhere in your production code. You might need changes to even make that possible.
If you have any use of Matchers in your verify call, you have to use them everywhere. For that purpose, there's a matcher (eq) for matching a value:
verify(mockedMethodInterceptor, times(1)).invoke(eq(expectedInvocation));
You don't need it here, but if your method had another argument where you wanted to use an any matcher, you'd need it.

Categories