How to mock method with arg 'T value'? - java

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.

Related

Mocking method if one argument is raw and other may be from list

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)

How to mock one method with different parameters multiple times?

I have some testing method:
#Test
public void test_method() {
MyObj mock = mock(MyObj.class);
when(mock.get("testName", "1")).thenReturn("Result1");
when(mock.get("test", "2")).thenReturn("rrrr");
}
when I trying run this method I had exception:
org.mockito.exceptions.misusing.PotentialStubbingProblem:
Strict stubbing argument mismatch. Please check:
Typically, stubbing argument mismatch indicates user mistake when writing tests.
Mockito fails early so that you can debug potential problem easily.
However, there are legit scenarios when this exception generates false negative signal:
- stubbing the same method multiple times using 'given().will()' or 'when().then()' API
Please use 'will().given()' or 'doReturn().when()' API for stubbing.
- stubbed method is intentionally invoked with different arguments by code under test
Please use default or 'silent' JUnit Rule (equivalent of Strictness.LENIENT).
For more information see javadoc for PotentialStubbingProblem class.
How can I mock this method?
The error message tells you:
stubbing the same method multiple times using 'given().will()' or 'when().then()' API
Please use 'will().given()' or 'doReturn().when()' API for stubbing.
You can use any() to mock one method with different parameters. any() will be used as a dynamic variable.
e.g doReturn(order).when(orderRepository).save(any(Order.class));
I was saving orderRepository with 2 different Order parameters so I have used any with Order class.

How to mock method with any arguments?

I write following row in my test:
when(Product.fromNode(any(Node.class), any(Locale.class),anyString())).thenReturn(productMock);
I see following error message:
you cannot use argument matchers outside of verification or stubbing
It is impposible because I can't use any at this case. But I don't know what concrete argument will be passed to the method but I know that I should handle it same.
What can you advice for me ?
Problem was that I used PowerMockito.mockStatic
but I used RunWith annotation different than:
#RunWith(PowerMockRunner.class)

Using Hamcrest matchers with JMock in Groovy

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/).

Mockito complains about wrong arguments

We try to verify the behaviour of an action with Mockito. The test code looks like this
final Type1 mock = mock(Type1.class);
new SomeAction<Type1>(mock).actionPerformed(null);
verify(mock).someMethod();
The method actionPerformed contains just the call of someMethod on the object provided in the constructor of Type1. Yet Mockito complains that the expected method call did not happen, instead a different method call happened. But the String representation of the two calls printed by Mockito are exactly the same!
Any explanation what is going on?
Update: ErrorMessage from Mockito
Argument(s) are different! Wanted:
type1.someMethod();
-> at xxx
Actual invocation has different arguments:
type1.someMethod();
-> at xxx
This is a bit of a stretch, but check your toString implementations. I've ran into some irritating unit test scenarios where the expected and observed appeared to be the same from the unit test point of view when in reality they were different. In the end it was a variation in toString that caused me to believe there was a similarity when in reality there was not.

Categories

Resources