InvalidUseOfMatchersException when mocking datasource - mockito

#Test
public void getRelationInteractionDataTest() throws Exception {
InteractionData iData = new InteractionData();
when(mockJdbcTemplate.getDataSource()).thenReturn(dataSource);
relationshipCheckDaoImpl.getRelationInteractionData(Mockito.anyString(), Mockito.anyString());
}
Exception:failed with = org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
0 matchers expected, 3 recorded:

relationshipCheckDaoImpl.getRelationInteractionData(Mockito.anyString(), Mockito.anyString());
While it may sound alluring to test a method with 'any' parameter, no, this isn't what matchers are for. Use actual values instead:
relationshipCheckDaoImpl.getRelationInteractionData("a", "b");
The reason is: You can use matchers when preparing a mock method...
Mockito.when( a.doB( Mockito.anyString() ) ).thenReturn("XYZ";
...or when verifying that something was called...
Mockito.verify( a ).doB( Mockito.anyString() );
...but not when calling the method itself, since what should the matchers match there? This will only confuse Mockito's internal system.

Related

Mocking a public method that has a private method call inside using Mockito (not Powermockito)

I am testing for methodA() in the class :
class Test{
public String methodA(String str){
...
methodB("s1","s2");
...
}
private String methodB(String s1, String s2){
...
}
}
What I have tried in my test class:
Method methodBReflect = Test.class.getDeclaredMethod("methodB", Test.class,String.class, String.class);
methodBReflect.setAccessible(true);
Test testForSpy=new Test();
Test spyTest=spy(testForSpy);
doReturn("return string").when(spyTest..)... // <-- What should be done here?
//methodBReflect.invoke(spyTest, "args1","args2");
P.S: I don't need a solution using powermock as I have some organizational constraints using it.
You shouldn't be testing that method A calls method B. You should test that method A does what method A is supposed to do - that is, it gives the correct output for whatever input you give it. Your test shouldn't care whether method A works by calling method B, or by doing all its processing inline.
Therefore, there's no need to mock or stub anything. Your tests will consist of a bunch of calls to method A, along with verification that the output is what you expect.
You only need to use Mockito (or some other mocking framework) when you're testing a class that interacts with another class entirely; not when the class under test interacts with itself.

Returning mock objects with Mockito using given arguments

For my JUnit Tests with Mockito, I am doing the following:
Mockito.lenient().when(tokenService.create(String id, Any)).thenReturn(new String (id))
Mockito.lenient().when(voucherRepo.findById(id String).thenReturn(new Voucher(id));
I would like to access the String id given to tokenService.create() and voucherRepo.findById() methods, create and then return mock objects using it. How it can be done?
Mockito.when(voucherRepo.findById(id)).thenReturn(new Voucher(id));
Your solution should work and is probably the preferred solution for any clear defined test.
As you know in your test what the exact id is, you can just return the specific object for it.
Another way to do this - for arbitrary strings - is using mockito's thenAnswer funtionality:
Mockito.when(voucherRepo.findById(Mockito.any(String.class))).thenAnswer(new Answer<Voucher>() {
#Override
public Voucher answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
String id = (String) args[0];
return new Voucher(id);
}
});
I am not sure what reason you have to do that in your test (as this a rather arbitrary defintion), but in doubt consider adding some more context to your question.

Getting InvalidUseOfMatchersException in the Mockito

I have written this java method:
public int run(String jobName) {
}
And I have written this test code:
#Test
public void testBatchStatusUpdateWithOneCompleteStatus() {
Set<BatchEntity> staleBatch = createStaleBatch();
Set<Integer> activeBatch = createActiveBatch();
when(batchRepository.findBatchIdByStateIn(
(Arrays.asList(BatchStates.IN_PROGRESS,
BatchStates.INTENT_MARKED)))).thenReturn(staleBatch);
when(listingRepository.findBatchId()).thenReturn(activeBatch);
Assert.assertEquals(batchStatusUpdate.run(Mockito.any(String.class)), 1);
Mockito.verify(batchRepository,Mockito.times(2)).save(Mockito.any(BatchEntity.class));
}
I am getting the below error when I run the
org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Invalid use of argument matchers! 0 matchers expected, 1 recorded: at backgroundjob.BatchStatusUpdateTest.testBatchStatusUpdateWithOneCompleteStatus This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String"); When using matchers, all arguments have to be provided by matchers. For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
For more info see javadoc for Matchers class.
I am getting this error when run method has the string argument. When I remove the string argument from the run method the test case is passed.
Mockito.any() creates a matcher, which is used when specifying a mock or when verifying calls with Mockito.verify(). They do not make sense as an argument to the method you are testing though. Your call should be changed to use an actual string, for example Assert.assertEquals(batchStatusUpdate.run("some value"), 1); instead of Assert.assertEquals(batchStatusUpdate.run(Mockito.any(String.class)), 1);

The test failure message for mockito verify

For a parameter class
class Criteria {
private Map params;
public getMap(){ return params; }
}
and a service method accept this criteria
class Service{
public List<Person> query(Criteria criteria){ ... }
}
A custom featureMatcher is used to match the criteria key
private Matcher<Criteria> hasCriteria(final String key, final Matcher<?> valueMatcher){
return new FeatureMatcher<Criteria, Object>((Matcher<? super Object>)valueMatcher, key, key){
#Override protected Object featureValueOf(Criteria actual){
return actual.getMap().get(key);
}
}
}
when using mockito to veryify the arguments:
verify(Service).query((Criteria) argThat("id", hasCriteria("id", equalTo(new Long(12)))));
The error message shows that:
Argument(s) are different! Wanted:
Service.query(
id <12L>
);
-> at app.TestTarget.test_id (TestTarget.java:134)
Actual invocation has different arguments:
Service.query(
app.Criteria#509f5011
);
If I use ArugmentCaptor,
ArgumentCaptor<Criteria> argument = ArgumentCaptor.forClass(Criteria.class);
verify(Service).query(argument.capture());
assertThat(argument.getValue(), hasCriteria("id", equalTo(new Long(12))));
The message is much better:
Expected: id <12L> but id was <2L>
How can I get such message, without using ArgumentCaptor?
The short answer is to adjust the Criteria code, if it's under your control, to write a better toString method. Otherwise, you may be better off using the ArgumentCaptor method.
Why is it hard to do without ArgumentCaptor? You know you're expecting one call, but Mockito was designed to handle it even if you have a dozen similar calls to evaluate. Even though you're using the same matcher implementation, with the same helpful describeMismatch implementation, assertThat inherently tries once to match where verify sees a mismatch and keeps trying to match any other call.
Consider this:
// in code:
dependency.call(true, false);
dependency.call(false, true);
dependency.call(false, false);
// in test:
verify(mockDependency).call(
argThat(is(equalTo(true))),
argThat(is(equalTo(true))));
Here, Mockito wouldn't know which of the calls was supposed to be call(true, true); any of the three might have been it. Instead, it only knows that there was a verification you were expecting that was never satisfied, and that one of three related calls might have been close. In your code with ArgumentCaptor, you can use your knowledge that there's only one call, and provide a more-sane error message; for Mockito, the best it can do is to output all the calls it DID receive, and without a helpful toString output for your Criteria, that's not very helpful at all.

groovy singleton to access overloaded constructor

groovy Singleton (NB at Groovy 2.6 you must set strict to false if you want to include the explicit constructor)
#Singleton( strict = false )
class test {
private test(){
//some Method call
}
private test(def x){
//some Method call
}
}
test.groovy
def test1 = test.instance
when i issue the following statement it works for me and i can see the defualt
constructor is called
how can i create instanace while using second construcor argument
if i issue
def test2 = test("anish").instance
it throws me error how do i resolve this any suggestion
groovy.lang.MissingMethodException: No signature of method: test.test() is applicable for argument types: (java.lang.String) values: [anish]
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:54)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:78)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:143)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:151)
In the first case you are accessing the static property test.instance, which in turn calls the static method test.getInstance(). In the second case, it looks like you are trying to call the second constructor as a method. That's not valid groovy: you need to use the new keyword to create an instance, which triggers the constructor. Also, making the constructor private makes it inaccessible except within the class itself.
If you need to instantiate another instance, it probably shouldn't be a singleton in the first place.

Resources