Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito matcher that compares items in Set, not the Set reference itself

when(validator.isValid(Sets.newHashSet("valid"))).thenReturn(true);

When validator.isValid(set) is invoked it returns false. It is because the validator implementation creates a new set that is different that the passed one (reference is different) - the items in both sets are same.

I need to return true if sets contains same items regardless of sets instances.

Something similar to org.mockito.Matchers:

public static <T> Set<T> anySetOf(Class<T> clazz) {
        return (Set) reportMatcher(Any.ANY).returnSet();
}

except that I would pass instances not Class<T>.class.

And same for verify:

verify(validator, times(1)).isValid(Sets.newHashSet("valid"));

Is there such a matcher?

like image 680
Felix Avatar asked Jun 30 '15 05:06

Felix


People also ask

What can I use instead of Mockito matchers?

mockito. Matchers is deprecated, ArgumentMatchers should be used instead.

Can the Mockito Matcher methods be used as return values?

Matcher methods can't be used as return values; there is no way to phrase thenReturn(anyInt()) or thenReturn(any(Foo. class)) in Mockito, for instance. Mockito needs to know exactly which instance to return in stubbing calls, and will not choose an arbitrary return value for you.

What is EQ Mockito?

Mockito Argument Matcher - eq() When we use argument matchers, then all the arguments should use matchers. If we want to use a specific value for an argument, then we can use eq() method. when(mockFoo. bool(eq("false"), anyInt(), any(Object. class))).

How to compare two objects in Mockito?

Internally Mockito uses Point class’s equals() method to compare object that has been passed to the method as an argument with object configured as expected in verify() method. If equals() is not overridden then java.lang.Object’s equals() is used which compares only the references, i.e. if both variables point to one and the same object in heap.

Why do we use Argument matchers instead of equal () method in Mockito?

It extends ArgumentMatchers class to access all the matcher functions. 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.

What are the matchers available in Mockito?

Apart from lists, Mockito offers matchers for other classes (apart from native types). You can see them in the Mockito matchers documentation for 1.10.19 version, but here’s a list with the matchers for parameterizable classes: Maps. Collections. Sets. Their use is the same as for the lists, Matchers.anyMap (), etc. 4.1.

Why does Mockito fail to verify when object is created?

When providing expected a new object is created, references are not one and the same, so Mockito will fail the verification. In order to make verification works simplest solution is to implement equals () method in Point class. Personally, I’m not a big fan of changing production code for sake of testing.


1 Answers

Apparently JB Nizet is right. There is no need for a specific matcher.

I have tried to use my own matcher and then after removal it worked also:

public static class SetItemMatcher extends ArgumentMatcher<Set<String>> {
    public static Set<String> setOf(Set<String> items) {
        return argThat(new SetItemMatcher(items));
    }

    private final Set<String> expected;

    public SetItemMatcher(Set<String> expected) {
        this.expected = expected;
    }

    @Override
    public boolean matches(Object argument) {
        Set<?> actual = (Set<?>) argument;
        return actual.size() == expected.size()  && containsAllItems(actual);
    }

    private boolean containsAllItems(Set<?> actual) {
        for (Object o : actual) {
            if (!expected.contains(o)) {
                return false;
            }
        }
        return true;
    }
}
like image 164
Felix Avatar answered Oct 13 '22 00:10

Felix