Search code examples
junithamcrestspring-mvc-testassertj

AssertJ to Hamcrest equivalency (only for Spring MVC Test): How test each POJO item of a collection (with dates)


For a Spring Framework App, about Testing:

If in AssertJ is possible apply the following for a collection:

.containsExactly(tuple("087", "Peter", "Jordani", parse("1980-01-01")),
                 ...
                 tuple("088", "Isaias", "Jordano", parse("1980-01-01")))

What could be the best equivalent approximation of these three methods:

  • containsExactly
  • tuple
  • parse

To be applied in:

 .andExpect(model().attribute("personas", ???)

I did a research in google:

  • about collections there are samples for simple collections (String, Integer with hasItems)
  • about dates, is working only with Date objects, of course same type, but not with String too.

Solution

  • Please take a look on these tests examples:

    public class Test {
            private List<Person> personList;
            private Person peter = new Person("087", "Peter", parse("1980-01-01"));
            private Person john = new Person("081", "John", parse("1980-01-22"));
    
            @BeforeEach
            void setup() {
                personList = new ArrayList<>();
                personList.add(peter);
                personList.add(john);
            }
    
            @Test
            void assertjTest() {
                assertThat(personList).extracting("age", "name", "date")
                        .containsExactly(
                                tuple("087", "Peter", parse("1980-01-01")),
                                tuple("081", "John", parse("1980-01-22"))
                        );
            }
    
            @Test
            void hamcrestTest() {
                org.hamcrest.MatcherAssert.assertThat(personList,
                        contains(
                                allOf(
                                        hasProperty("age", is("087")),
                                        hasProperty("name", is("Peter")),
                                        hasProperty("date", is(parse("1980-01-01")))
                                ),
                                allOf(
                                        hasProperty("age", is("081")),
                                        hasProperty("name", is("John")),
                                        hasProperty("date", is(parse("1980-01-22")))
                                )
                        ));
    
            }
    }
    

    And let's review in details:

    containsExactly

    contains method is an alternative for it. Whereas hasItem is more like assertj.contains.

    tuple

    May be replaced by combination of allOf and hasProperty. In my opinion it looks ugly and I would think about just using new Person("a","b","c"). Unless you have some extra fields that you do not want to verify.

    parse

    Here I've just used same method for both of them. If you will take a more precise look on it, you will notice that this method has nothing to do with matchers. It is just parses string to date using new SimpleDateFormat("yyyy-MM-dd"). If you don't want to use assertj's you could easily extract it to some util class.