Skip to content
Advertisement

Mockito; verify method was called with list, ignore order of elements in list

I have a class (ClassA) that get the files in a directory. It scans the given directory for files matching a regex. For each matching file, it adds a File Object to a list. Once the directory is processed, it passes the List of Files to another Class (ClassB) for processing

I am writing unit tests for ClassA, so am mocking ClassB using Mockito, and injecting it into ClassA. I then want to verify in different scenarios the contents of the list that is passed to ClassB (ie my mock)

I’ve stripped back the code to the following

JavaScript

The test class looks like this

JavaScript

The problem is that this test works perfectly fine on windows, but fails on Linux. The reason being that on windows, the order that ClassA list the files matches the expectedList, so the line

JavaScript

is causing the problem expecetdFileList = {FileA, FileB, FileC} on Windows, whereas on Linux it will be {FileC, FileB, FileA}, so the verify fails.

The question is, how do I get around this in Mockito. Is there any way of saying, I expect this method to be be called with this parameter, but I don’t care about the order of the contents of the list.

I do have a solution, I just don’t like it, I would rather have a cleaner, easier to read solution.

I can use an ArgumentCaptor to get the actual value passed into the mock, then can sort it, and compare it to my expected values.

JavaScript

Advertisement

Answer

As noted in another answer, if you don’t care about the order, you might do best to change the interface so it doesn’t care about the order.

If order matters in the code but not in a specific test, you can use the ArgumentCaptor as you did. It clutters the code a bit.

If this is something you might do in multiple tests, you might do better to use appropriate Mockito Matchers or Hamcrest Matchers, or roll your own (if you don’t find one that fills the need). A hamcrest matcher might be best as it can be used in other contexts besides mockito.

For this example you could create a hamcrest matcher as follows:

JavaScript

And then the verify code becomes:

JavaScript

If you instead created a mockito matcher, you wouldn’t need the argThat, which basically wraps a hamcrest matcher in a mockito matcher.

This moves the logic of sorting or converting to set out of your test and makes it reusable.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement