Is there a mockito eq matcher for the varargs array?

I have a problem trying to match an array that is passed as a parameter to the method that the varargs array receives.

The anyVararg () connector mentioned in other questions / answers does not work for me because I want to make sure that the provided array is the one I need.

I brought a problem to this example, which is easier to understand and abstract the problem (my real problem is the production code and the logic of business processes, so it would be incomprehensible for the purpose of this question):

@RunWith(MockitoJUnitRunner.class) public class UnitTest { private Object[] objectArray; private List<Object> expected; private TestTarget target; @Before public void setUp() { objectArray = new Object[]{ new Object() }; expected = Arrays.asList(new Object(), new Object()); target = Mockito.spy(new TestTarget()); } @Test public void testMakeList() { // this pass as eq works well with normal array doReturn(expected).when(target).toList(Mockito.eq(objectArray)); Assert.assertEquals(expected, target.makeList(objectArray)); } @Test public void testMakeList1() { // this one fails as eq is not working with varargs doReturn(expected).when(target).toList1(Mockito.eq(objectArray)); Assert.assertEquals(expected, target.makeList1(objectArray)); } @Test public void testMakeListWithAryEq() { // fails, aryEq is not working with varargs doReturn(expected).when(target).toList1(AdditionalMatchers.aryEq(objectArray)); Assert.assertEquals(expected, target.makeList1(objectArray)); } private class TestTarget { public List<Object> makeList(Object[] objects) { return toList(objects); } public List<Object> makeList1(Object[] objects) { return toList1(objects); } protected List<Object> toList(Object[] objs) { return null; // Not implemented "Intentionally" } protected List<Object> toList1(Object... objs) { return null; // Not implemented "Intentionally" } } } 

When I run the test cases in the class, the first test case will pass, but not the other two, not using eq and not using aryEq. Display the following track:

 java.lang.AssertionError: expected:<[ java.lang.Object@56d5e457 , java.lang.Object@7482384a ]> but was:<null> at org.junit.Assert.fail(Assert.java:88) at org.junit.Assert.failNotEquals(Assert.java:743) at org.junit.Assert.assertEquals(Assert.java:118) at org.junit.Assert.assertEquals(Assert.java:144) ... 

This is due to the fact that eq pairing does not work with varargs arrays, is there any alternative for eq pairing for this use case?

+7
java junit mockito
source share
2 answers

Well, I think that here we need a special user connector, which can be implemented in your unit test as follows:

 private class MyVarargMatcher extends ArgumentMatcher<Object[]> implements VarargMatcher { private Object[] expectedValues; MyVarargMatcher(Object... expectedValues) { this.expectedValues = expectedValues; } @Override public boolean matches(Object varargArgument) { return new EqualsBuilder() .append(expectedValues, varargArgument) .isEquals(); } } 

Then in testMakeList1() change the first line to this:

 Mockito.doReturn(expected).when(target).toList1(Mockito.argThat(new MyVarargMatcher(objectArray))); 

Sources:
How to match varargs in Mockito correctly
http://maciejmadej.blogspot.com/2011/11/capturing-varargs-argument-using-custom.html

+6
source share

This is not a problem with varargs mapping. The only limitation is that you must specify each individual array entry as a consistent argument. I updated your code below to show what I mean. I created a second objectArray2 to make the point clearer. All tests pass:

 @RunWith(MockitoJUnitRunner.class) public class UnitTest { private Object[] objectArray; private Object[] objectArray2; private List<Object> expected; private TestTarget target; private Object obj,obj2; @Before public void setUp() { obj = new Object(); obj2 = new Object(); objectArray = new Object[]{ obj }; objectArray2 = new Object[]{ obj, obj2 }; expected = Arrays.asList(new Object(), new Object()); target = Mockito.spy(new TestTarget()); } @Test public void testMakeList() { // this pass as eq works well with normal array doReturn(expected).when(target).toList(Mockito.eq(objectArray)); Assert.assertEquals(expected, target.makeList(objectArray)); } @Test public void testMakeList1() { // since objectArray has one entry you need to add one matching argument doReturn(expected).when(target).toList1(Mockito.eq(obj)); Assert.assertEquals(expected, target.makeList1(objectArray)); } @Test public void testMakeListWithAryEq() { // since objectArray2 has two entries you need to add two matching arguments doReturn(expected).when(target).toList1(Mockito.eq(obj),Mockito.eq(obj2)); Assert.assertEquals(expected, target.makeList1(objectArray2)); } private class TestTarget { public List<Object> makeList(Object[] objects) { return toList(objects); } public List<Object> makeList1(Object[] objects) { return toList1(objects); } protected List<Object> toList(Object[] objs) { return null; // Not implemented "Intentionally" } protected List<Object> toList1(Object... objs) { return null; // Not implemented "Intentionally" } } } 
0
source share

All Articles