Issue
I have a test that is intended to test the contents of an Array of objects (a set of rules that use a Rule wrapper class) that get returned from a DB:
[
{
id: 1,
name: "rule_1",
description: "this rule will check something",
},
]
@Test
public void testQueryRules() throws IOException {
final List<Rule> rules = ruleDB.queryRules();
final String expectedRuleId = "1";
final String expectedName = "rule_1";
final String expectedDescription = "this rule will check something";
final Rule rule = new Rule(expectedRuleId, expectedName, expectedDescription);
final List<Rule> expectedRules = new ArrayList<Rule>();
expectedRules.add(rule);
expectedRules.forEach(expectedRule -> {
System.out.println("RULE ID " + expectedRule.getRuleId());
System.out.println("RULE NAME " + expectedRule.getRuleName());
System.out.println("RULE DESCRIPTION " + expectedRule.getDescription());
});
rules.forEach(actualRule -> {
System.out.println("ACTUAL RULE ID " + actualRule.getRuleId());
System.out.println("ACTUAL RULE NAME " + actualRule.getRuleName());
System.out.println("ACTUAL DESCRIPTION " + actualRule.getDescription());
});
System.out.println("MATCHED " + Arrays.deepEquals(expectedRules.toArray(), rules.toArray()));
System.out.println("MATCHED AGAIN " + Arrays.equals(expectedRules.toArray(), rules.toArray()));
Assert.assertArrayEquals(expectedRules.toArray(), rules.toArray());
}
As you can see, I've tried using Arrays.equals()
, as well as Arrays.deepEquals()
, and assertArrayEquals()
. None of those seem to give a successful test even though the output of both the expected and actual is the same:
EXPECTED:
RULE ID: 1
RULE NAME: "rule 1",
RULE DESCRIPTION: "this rule will check something",
ACTUAL:
ACTUAL RULE ID: 1
ACTUAL RULE NAME: "rule 1",
ACTUAL RULE DESCRIPTION: "this rule will check something"
What is the standard way to test arrays of objects in Java? It seems like its failing because the pointer reference is different even though the contents is the same.
Solution
You might want to use assertj for that. Especially its usingFieldByFieldElementComparator
import java.util.Arrays;
import java.util.List;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
class MyTests {
static class Rule {
final String id;
final String name;
final String description;
Rule(String id, String name, String description) {
this.id = id;
this.name = name;
this.description = description;
}
// no equals, no hashCode
}
@Test
void rulesShouldEqual_whenTheirPropertiesEqual() {
Rule actualRule1 = new Rule("id1", "name1", "description1");
Rule actualRule2 = new Rule("id2", "name2", "description2");
List<Rule> actual = Arrays.asList(actualRule1, actualRule2);
Assertions.assertThat(actual).usingFieldByFieldElementComparator().containsExactly(
new Rule("id1", "name1", "description1"),
new Rule("id2", "name2", "description2"));
}
}
Answered By - Frank Neblung