There is a generic method that takes a class as parameter and I have problems stubbing it with Mockito. The method looks like this:
public <U extends Enum<U> & Error, T extends ServiceResponse<U>> T validate( Object target, Validator validator, Class<T> responseClass, Class<U> errorEnum);
It's god awful, at least to me... I could imagine living without it, but the rest of the code base happily uses it...
I was going to, in my unit test, stub this method to return a new empty object. But how do I do this with mockito? I tried:
when(serviceValidatorStub.validate( any(), isA(UserCommentRequestValidator.class), UserCommentResponse.class, UserCommentError.class) ).thenReturn(new UserCommentResponse());
but since I am mixing and matching matchers and raw values, I get "org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Invalid use of argument matchers!"
A stub is a fake class that comes with preprogrammed return values. It's injected into the class under test to give you absolute control over what's being tested as input. A typical stub is a database connection that allows you to mimic any scenario without having a real database.
Mockito uses equal() as a legacy method for verification and matching of argument values. In some cases, we need more flexibility during the verification of argument values, so we should use argument matchers instead of equal() method. The ArgumentMatchers class is available in org. mockito package.
mockito. Matchers is deprecated, ArgumentMatchers should be used instead.
The Mockito. mock() method allows us to create a mock object of a class or an interface. We can then use the mock to stub return values for its methods and verify if they were called.
The problem is, you cannot mix argument matchers and real arguments in a mocked call. So, rather do this:
when(serviceValidatorStub.validate( any(), isA(UserCommentRequestValidator.class), eq(UserCommentResponse.class), eq(UserCommentError.class)) ).thenReturn(new UserCommentResponse());
Notice the use of the eq()
argument matcher for matching equality.
see: https://static.javadoc.io/org.mockito/mockito-core/1.10.19/org/mockito/Matchers.html#eq(T)
Also, you could use the same()
argument matcher for Class<?>
types - this matches same identity, like the ==
Java operator.
Just in order to complete on the same thread, if someone want to stubb a method that takes a Class as argument, but don't care of the type, or need many type to be stubbed the same way, here is another solution:
private class AnyClassMatcher extends ArgumentMatcher<Class<?>> { @Override public boolean matches(final Object argument) { // We always return true, because we want to acknowledge all class types return true; } } private Class<?> anyClass() { return Mockito.argThat(new AnyClassMatcher()); }
and then call
Mockito.when(mock.doIt(this.anyClass())).thenCallRealMethod();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With