Search code examples
javajunitassertj

How to compare iterators content in unit test?


I have two java.util.Scanner objects. Scanner class implements Iterator<String>. I wanna compare scanners and have easy ability to see what lines are different.

Currently I use AssertJ soft assertions in this way

@Rule
JUnitSoftAssertions softly = new JUnitSoftAssertions();
...
Scanner actual = ...
Scanner expected = ...

int i = 0;
while (actual.hasNext() && expected.hasNext()) {
  softly.assertThat(actual.next()).as("line %s", i++).isEqualTo(expected.next());
}

This code insn't perfect but whether is ability in AssertJ to do this in one assertion?

I see static IterableAssert<ELEMENT> assertThat(Iterator<? extends ELEMENT> actual) method in Assertions class but can't see appropriate check method in IterableAssert.


Solution

  • The docs say:

    softly.assertThat(actual).containsExactlyElementsOf(expected);
    

    See: http://joel-costigliola.github.io/assertj/core/api/org/assertj/core/api/AbstractIterableAssert.html#containsExactlyElementsOf(java.lang.Iterable)

    So, you could create a custom Iterable that returns your scanners

    public class ScannerIterable implements Iterable<String> {
    
        private Scanner scanner;
    
        public ScanerIterable(Scanner scanner) {
            this.scanner = scanner;
        }
    
        @Override
        public Iterator<String> iterator() {
            return scanner;
        }
    }
    

    This could be made generic, so it could take in any kind of Iterator.