Mockito. Verify method arguments

0 votes
asked Aug 24, 2010 by manolowar

I've googled about this, but didn't find anything relevant. I've got something like this:

Object obj = getObject();
Mockeable mock= Mockito.mock(Mockeable.class);
Mockito.when(mock.mymethod(obj )).thenReturn(null);

Testeable obj = new Testeable();
obj.setMockeable(mock);
command.runtestmethod();

Now, I want to verify that mymethod(Object o), which is called inside runtestmethod(), was called with the Object o, not any other. But I always pass the test, whatever I put on the verification, for example, with:

Mockito.verify(mock.mymethod(Mockito.eq(obj)));

or

Mockito.verify(mock.mymethod(Mockito.eq(null)));

or

Mockito.verify(mock.mymethod(Mockito.eq("something_else")));

I always pass the test. How can I accomplish that verification (if possible)?

Thank you.

7 Answers

0 votes
answered Aug 24, 2010 by bozho
  • You don't need the eq matcher if you don't use other matchers.
  • You are not using the correct syntax - your method call should be outside the .verify(mock). You are now initiating verification on the result of the method call, without verifying anything (not making a method call). Hence all tests are passing.

You code should look like:

Mockito.verify(mock).mymethod(obj);
Mockito.verify(mock).mymethod(null);
Mockito.verify(mock).mymethod("something_else");
0 votes
answered Aug 2, 2012 by rit

Have you checked the equals method for the mockable class? If this one returns always true or you test the same instance against the same instance and the equal method is not overwritten (and therefor only checks against the references), then it returns true.

0 votes
answered Aug 2, 2013 by matthew-kirkley

Are you trying to do logical equality utilizing the object's .equals method? You can do this utilizing the argThat matcher that is included in Mockito

import static org.mockito.Matchers.argThat

Next you can implement your own argument matcher that will defer to each objects .equals method

private class ObjectEqualityArgumentMatcher<T> extends ArgumentMatcher<T> {
    T thisObject;

    public ObjectEqualityArgumentMatcher(T thisObject) {
        this.thisObject = thisObject;
    }

    @Override
    public boolean matches(Object argument) {
        return thisObject.equals(argument);
    }
}

Now using your code you can update it to read...

Object obj = getObject();
Mockeable mock= Mockito.mock(Mockeable.class);
Mockito.when(mock.mymethod(obj)).thenReturn(null);

Testeable obj = new Testeable();
obj.setMockeable(mock);
command.runtestmethod();

verify(mock).mymethod(argThat(new ObjectEqualityArgumentMatcher<Object>(obj)));

If you are just going for EXACT equality (same object in memory), just do

verify(mock).mymethod(obj);

This will verify it was called once.

0 votes
answered Aug 3, 2015 by cbbcloud

Have you tried it with the same() matcher? As in:

verify(mockObj).someMethod(same(specificInstance));

I had the same problem. I tried it with the eq() matcher as well as the refEq() matcher but I always had false positives. When I used the same() matcher, the test failed when the arguments were different instances and passed once the arguments were the same instance.

0 votes
answered Aug 19, 2015 by eugene82

An alternative to ArgumentMatcher is ArgumentCaptor.

Official example:

ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
verify(mock).doSomething(argument.capture());
assertEquals("John", argument.getValue().getName());

A captor can also be defined using the @Captor annotation:

@Captor ArgumentCaptor<Person> captor;
//... MockitoAnnotations.initMocks(this);
@Test public void test() {
    //...
    verify(mock).doSomething(captor.capture());
    assertEquals("John", captor.getValue().getName());
}
0 votes
answered Aug 8, 2016 by nils-renaud

The other method is to use the org.mockito.internal.matchers.Equals.Equals method instead of redefining one :

verify(myMock).myMethod((inputObject)Mockito.argThat(new Equals(inputObjectWanted)));
0 votes
answered Aug 17, 2016 by sendon1982

You can also use TypeSafeDiagnosingMatcher

    private Matcher<GetPackagesRequest> expectedPackageRequest(final AvailabilityRequest request) {
    return new TypeSafeDiagnosingMatcher<GetPackagesRequest>() {

        StringBuilder text = new StringBuilder(500);

        @Override
        protected boolean matchesSafely(GetPackagesRequest req, Description desc) {
            String productCode = req.getPackageIds().iterator().next().getValue();
            if (productCode.equals(request.getSupplierProductCode())) {
                text.append("ProductCode not equal! " + productCode + " , " + request.getSupplierProductCode());
                return true;
            }

            text.append(req.toString());
            return false;
        }

        @Override
        public void describeTo(Description d) {
            d.appendText(text.toString());
        }
    };
}

Then verify that invocation:

Mockito.verify(client).getPackages(Mockito.argThat(expectedPackageRequest(request)));
Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...