Pablo
Pablo

Reputation: 3467

Mockito mock object with list argument's contents

I've faced this situation pretty often and don't know how to resolve it using Mockito's default methods such as (any, anyList, eq)

For example I have an object where I want to mock a method expecting a list which contains other mocked objects. Let me explain:

public class MyMapper {
   public List<DataObjects> convertList(List<String> rawContents) {
      rawContents.stream().map(r -> convertObject(r))
      .collect(Collectors.toList());
   }

   public DataObject convertObject(String rawContent) {
       return new DataObject(rawContent);
   }
} 

public class MyWorkerClass {
     public boolean start(List<String> rawContents) {
           List<DataObject> objects = new MyMapper().convertList(rawContents);
           return publish(objects);
     }

     public boolean result publish(List<DataObject> objects) {
           ../// some logic
     }
}

Now what I want to assert is something like. Note: Please assume the right mocks are returned when new() is called [Using some PowerMockito]

@Test
public void test() {
   String content = "content";
   DataObject mock1 = Mockito.mock(DataObject.class);
   MyMapper mapperMock = Mockito.mock(MyMapper.class);
   MyWorkerClass worker = new MyWorkerClass();

   Mockito.when(mapperMock.convertObject(content)).thenReturn(mock1);

   Mockito.when(worker.publish(eq(Arrays.asList(mock1)).thenReturn(true);

   boolean result = worker.start(Arrays.asList(content));
   Assert.assertTrue(result);
}

The problem with the code above is in the line

  Mockito.when(worker.publish(eq(Arrays.asList(mock1)).thenReturn(true);

This will try to match the list object instead of the list contents, in other words, even when I have to lists A: [mock1] and B: [mock1], A is not equal to B and ultimately the stubbing fails.

What I need is some sort of matcher similar to hamcrest's contain matcher. Something like:

  Mockito.when(worker.publish(contains(mock1)).thenReturn(true));

Is there anyway I can achieve this? Keep in mind the code above is just an example to grasp the problem, the real situation is a little bit more complex and I can only mock individual objects, not the list itself

Thanks

Upvotes: 2

Views: 6737

Answers (1)

Pablo
Pablo

Reputation: 3467

Nevermind, later I learned that Mockito's eq() method will call the equals() method on the argument. Now if that is an ArrayList it means it will return true if two list sizes are equal and if the equal's comparison for each one of the elements in the list also returns true. See https://docs.oracle.com/javase/6/docs/api/java/util/List.html#equals%28java.lang.Object%29

And for even more customization argThat() could be used What's the difference between Mockito Matchers isA, any, eq, and same?

Upvotes: 2

Related Questions