I'm new to Groovy (and to JMock too for that matter) and having some trouble building expectations that use matchers on the parameters of the methods being mocked. When I try to do something like this:
Expectations e = new Expectations();
e.allowing(mockObject).doSomething(Expectations.with(aNonNull(ImmutableCollection.class)))
e.will(returnValue(someResponse))
It causes the following error when building the expectation:
groovy.lang.MissingMethodException: No signature of method: static org.jmock.Expectations.with() is applicable for argument types: (org.hamcrest.core.IsNot) values: [not null]
Possible solutions: with(boolean), with(org.hamcrest.Matcher), with(byte), with(org.hamcrest.Matcher), with(char), with(org.hamcrest.Matcher)
aNonNull returns Matcher<T> (org.hamcrest.core.IsNot implements Matcher<T>) and there is an Expectations.with method that takes a Matcher so I'm not sure why Groovy is trying to find a version of with that takes the concrete class rather than the interface specified by aNonNull. I've also tried casting the return value of aNonNull to both Matcher and Matcher<T> without any change in the error. I'm not sure if there's something about the generics that's confusing Groovy or what else to check.
According to the JavaDoc, org.jmock.Expectations.with() is an instance rather than a static method. That's why you get an error.
By the way, testing/mocking frameworks built specifically for Groovy will make your life a lot easier (even when testing Java code). For example, the same expectation looks like this in Spock (http://spockframework.org):
mockObject.doSomething(_ as ImmutableCollection) >> someResponse
Another Groovy mocking framework to be aware of is GMock (http://code.google.com/p/gmock/).
Related
I'm using Kotlin 1.6.10, Mockito 4.0.0 and Java 8 and I have a Java interface defined like this:
public interface MyInterface {
<D, T extends MyObject<T, D>> T doThings(T myObject);
}
An implementation of this interface is used in a Kotlin application and we have a unit test in which we want to make sure that the doThings method is never called using Mockito. In Java I would just do like this:
verify(myInterfaceInstance, never()).doThings(any());
But if I do this in Kotlin I get a compile-time error:
verify(myInterfaceInstance, never()).doThings(any())
Not enough information to infer type variable D
I understand why this is the case, but I cannot get it to work. In this particular case I really don't care about the generic types, I just want to make sure the doThings is never called. I've tried a lot of different things, for example:
verify(myInterfaceInstance, never()).doThings<Any, MyObject<*, Any>>(any())
which fails with:
Type argument is not within its bounds.
Expected:
MyObject<MyObject<*, Any>!, TypeVariable(D)!>!
Found:
MyObject<*, Any!>!
and I've also tried:
verify(myInterfaceInstance, never()).doThings<Any, MyObject<*, *>>(any())
and several other permutations which all seem to fail with roughly the same error message.
So my question is, how can I do the equivalent of Java's verify(myInterfaceInstance, never()).doThings(any()); in Kotlin?
This compiles fine, but issues a couple of warnings, you could suppress them via respectful annotation:
#Suppress("TYPE_MISMATCH_WARNING", "UPPER_BOUND_VIOLATED_WARNING")
verify(myInterfaceInstance, never()).doThings<Any, MyObject<*, *>?>(any<MyObject<*, *>>())
This is not a Mockito answer, but would the Library Mockk help you? MockK is built specifically for Kotlin so it might have better supports for Generics handling.
The verification would look like:
verify(exactly = 0) { yourClass.doThings(any()) };
https://notwoods.github.io/mockk-guidebook/docs/mocking/verify/
https://mockk.io/#verification-atleast-atmost-or-exactly-times
I want to test if method was invoked X times with one raw argument and other arguments from list. I found this method:
Mockito.verify(mock,Mockito.times(3)).myMethod(Mockito.eq("lastName"),
Mockito.argThat(Matchers.isOneOf("firstName","name","firstName"))));
However this complains that argThat method needs ArgumentMatcher but Matchers.isOneOf returns org.hamcrest.Matcher
Is there any other way that i could achieve this?
Thanks for help!
This changed in Mockito 2.1.0. On the Mockito web site, there is this migration advice.
All existing custom implementations of ArgumentMatcher will no longer
compile. All locations where hamcrest matchers are passed to argThat()
will no longer compile. There are 2 approaches to fix the problems:
a) Refactor the hamcrest matcher to Mockito matcher: Use implements
ArgumentMatcher instead of extends ArgumentMatcher. Then refactor
describeTo() method into toString() method.
b) Use org.mockito.hamcrest.MockitoHamcrest.argThat() instead of
Mockito.argThat(). Ensure that there is hamcrest dependency on
classpath (Mockito does not depend on hamcrest any more).
What option
is right for you? If you don't mind compile dependency to hamcrest
then option b) is probably right for you. Your choice should not have
big impact and is fully reversible - you can choose different option
in future (and refactor the code)
I'm trying to port a Scala system to Mockito2. There are a few test cases that use doReturn and now in Mockito 2.18.0 I get this error:
Error:(34, 5) ambiguous reference to overloaded definition,
both method doReturn in object Mockito of type (x$1: Any, x$2: Object*)org.mockito.stubbing.Stubber
and method doReturn in object Mockito of type (x$1: Any)org.mockito.stubbing.Stubber
match argument types (com.twitter.util.Future[Unit])
doReturn(Future.Unit).when(f.adapterSpy).myFunction(userData, Some(offerId), Always)
Looking in Mockito.java, doReturn is really overloaded like that:
public static Stubber doReturn(Object toBeReturned)
public static Stubber doReturn(Object toBeReturned, Object... toBeReturnedNext)
How on Earth is this not always ambiguous? How do I make it compile?
Thanks
As a temporary workaround, you can do the following:
trait MockitoHelper extends MockitoSugar {
def doReturn(toBeReturned: Any): Stubber = {
Mockito.doReturn(toBeReturned, Nil: _*)
}
}
Then have your test mixin this MockitoHelper.
This can also be overcome by using doAnswer instead of doReturn
// no good
doReturn(true).when(foo).bar()
// works
doAnswer(_ => true).when(foo).bar()
There is a ticket in the Scala backlog on it. see https://github.com/scala/bug/issues/4775
This is a bit of self promotion but I just published a library called mockito-scala that solves this issue and many more, is part of the mockito ecosystem so hopefully should become the default when working with Scala, you can find it here https://github.com/mockito/mockito-scala with the information to get the dependency and what problems does it actually solves.
Specifically for your problem, you could write this code and it would work out of the box
doReturn(Future.successful(())).when(f.adapterSpy).myFunction(userData, Some(offerId), Always)
I changed the way the future is expressed just because is the correct way to create a completed future of Unit
I have a code that I want to unit test. The code uses Collections.sort method providing it with our own sweet comparator something like :
List<Something> something = somethingService.doSomething(someParameter);
Collections.sort(something, somethingComparator);
Now while testing the function I am mocking the somethingService and stubbing the doSomething method like :
List<Something> mockList = Mockito.mock(List.class);
Mockito.when(somethingService.doSomething(anyInt())).thenReturn(mockList);
and I am mocking the Collections as :
PowerMockito.mockStatic(Collections.class);
PowerMockito.doNothing().when(Collections.class, "sort", anyListOf(Something.class), anyOf(Comparator.class));
But it is giving me :
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced argument matcher detected
You cannot use argument matchers outside of verification or stubbing.
Now I do know that if we are using argument matchers in any param of a function we need to provide matchers to all the params. But here is it possible to do the same and if not then what is the existing workaround?
You are using PowerMock to mock a system class from the JDK, design wise it's really, really nasty. Seriously one should really think over his motivation to use Powermock as the author himself is.
Powermock cannot really mock directly static methods from system class, you have to create wrappers around the system calls, as documented in the wiki.
I would strongly advises you to extract some sorting strategy, that you could mock with just Mockito.
I have such method:
<T extends Entity> boolean putObject(T value);
But can`t find out how to mock it using mockito? anyObject() and any() produce error:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
1 matchers expected, 3 recorded.
Mock:
when(service.putObject(any(ProcessingTransaction.class))).thenReturn(true);
How it shold work?
Most likely, you have one or two improperly-formed calls to Mockito methods, somewhere earlier in your test (or even in a previous test). When you call a Mockito method that makes an argument matcher (like any()), the matcher gets added to an internal data structure. It's then removed when it's actually used.
The fact that Mockito found three argument matchers instead of just one suggests that you made some argument matchers but didn't use them. For example, if you use when(...) without thenReturn(), this can happen; but there are lots of other cases too.
If you want help finding exactly what you've done wrong, you need to post more of your test code.