Hamcrest matcher to compare two arrays
Asked Answered
I

3

11

I have a method that do sort an array, and I want to test it, I want to compare its result with the expected one, of course that I can do it using a for loop, but i'm asking if there is a Hamcrest matcher to do the comparison

I have a class

class Person{
 String name;
 int age;
 double budget;
 Person(String name,int age,double budget){
  this.name = name;
  this.age = age;
  this.budget = budget;
 }
 @Override
 public boolean equals(Object obj) {
   if (obj == null || !(obj instanceof Person)) return false;
   Person p = (Person) obj;
   if (((Person) obj).budget == budget && ((Person) obj).age == age && ((Person) obj).name.equals(name)) {
    return true;
   }
   return false;
 }
}

and my test method is like this

@Test
public void InsertionSortOfObjectUsingComparator() {
    Person p1 = new Person("A", 18, 800);
    Person p2 = new Person("K", 15, 1800);
    Person p3 = new Person("L", 18, 600);
    Person[] persons = {p1,p2,p3};
    Person[] expected = {p3, p1, p2};
    Person[] result = (new Sort()).sort(persons, Comparator.<Person>comparingDouble(o-> o.budget);
    //want to compare the content of the two arrays result and expected; using assertThat
}

Is it possible doing it using Hamcrest ? if yes, how ?

UPDATE

yes it is possible, using IsArrayContainingInOrder.arrayContaining

    ....
    assertThat(expected, IsArrayContainingInOrder.arrayContaining((new InsertionSort().sort(persons, Comparator.comparingDouble(o -> o.budget)))));
    assertThat(3,is((new InsertionSort().sort(persons, Comparator.comparingDouble(o -> o.budget))).length));
}
Instrumentation answered 30/1, 2019 at 11:32 Comment(0)
C
8

There are many ways that you could do this with hamcrest. The easiest way is to use the arrayContaining matcher in Matchers class.

assertThat(result, Matchers.arrayContaining(expected));
Consumption answered 30/1, 2019 at 11:48 Comment(5)
thanks for your answer, yes I agree with you the Matchers.arrayContaining check that the objects in result are in the expected array, but it's negligate the ordre which i'm currently testingInstrumentation
The arrayContaining matcher fails if order is different. There's another matcher called arrayContainingInAnyOrder, I think that's what you are referring to. Have you tried this?Consumption
Thank you what i was looking is this IsArrayContainingInOrder.arrayContaining it test the order of the array tooInstrumentation
If this solution has worked please accept the answer. Thanks.Consumption
arrayContaining() will not compile when expected is a primitive array: byte[] result = byte[] { 0x01, 0x02, 0x03 }; byte[] exepected = byte[] { 0x01, 0x02, 0x03 }; assertThat(result, Matches.arrayContaining(expected)) will complain: The method assertThat(T, Matcher<? super T>) in the type MatcherAssert is not applicable for the arguments (byte[], Matcher<byte[][]>)Civil
M
10

The arrays can be matched with the simplest is matcher, e.g.:

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;

// ...

assertThat(result, is(new byte[]{1, 2, 3}));

Under the hood it will figure out that the input is an array. It will use the appropriate matcher for arrays (i.e. not just a.equal(b)).

Middlesworth answered 14/4, 2020 at 14:12 Comment(0)
C
8

There are many ways that you could do this with hamcrest. The easiest way is to use the arrayContaining matcher in Matchers class.

assertThat(result, Matchers.arrayContaining(expected));
Consumption answered 30/1, 2019 at 11:48 Comment(5)
thanks for your answer, yes I agree with you the Matchers.arrayContaining check that the objects in result are in the expected array, but it's negligate the ordre which i'm currently testingInstrumentation
The arrayContaining matcher fails if order is different. There's another matcher called arrayContainingInAnyOrder, I think that's what you are referring to. Have you tried this?Consumption
Thank you what i was looking is this IsArrayContainingInOrder.arrayContaining it test the order of the array tooInstrumentation
If this solution has worked please accept the answer. Thanks.Consumption
arrayContaining() will not compile when expected is a primitive array: byte[] result = byte[] { 0x01, 0x02, 0x03 }; byte[] exepected = byte[] { 0x01, 0x02, 0x03 }; assertThat(result, Matches.arrayContaining(expected)) will complain: The method assertThat(T, Matcher<? super T>) in the type MatcherAssert is not applicable for the arguments (byte[], Matcher<byte[][]>)Civil
S
0

Junit also has a built in assertArrayEquals ( https://junit.org/junit4/javadoc/4.12/org/junit/Assert.html#assertArrayEquals(java.lang.Object[],%20java.lang.Object[]) )

It recursively checks equality if your arrays contain arrays. Pretty handy, and very declarative and easy to read!

Separation answered 23/7, 2021 at 4:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.