Does assertEquals(Object o1, Object o2) uses the equals method
JavaJunitJava Problem Overview
In other words, does assertEquals works with a class that overrides equals
Java Solutions
Solution 1 - Java
From the source code of the assertEquals method that you can find on the Junit GitHub Repo:
/**
* Asserts that two objects are equal. If they are not
* an AssertionFailedError is thrown with the given message.
*/
static public void assertEquals(String message, Object expected, Object actual) {
if (expected == null && actual == null) {
return;
}
if (expected != null && expected.equals(actual)) {
return;
}
failNotEquals(message, expected, actual);
}
You can see that Junit is using the .equals()
method.
Edit:
The code snippet is coming from a deprecated version of Junit.
You can read about the source of the 'new' Junit here. The idea is pretty much the same, the .equals()
method is also used.
Solution 2 - Java
> does assertEquals works with a class that overrides equals?
Yes, assertEquals()
invokes the overridden equals()
if the class has one.
Solution 3 - Java
Yes, it calls equals
and there is a separate method, assertSame
, that uses ==
. Just to clear things up, assertEquals
works with any object since all objects declare equals
.
Solution 4 - Java
Yes it does.
Object m = new Object() {
@Override
public boolean equals(Object obj) {
System.out.println("proof!");
return super.equals(obj);
}
};
Assert.assertEquals(m, m);
Solution 5 - Java
JUnit is opensource, so you could have looked it up yourself in the source: https://github.com/junit-team/junit4/blob/master/src/main/java/org/junit/Assert.java
static public void assertEquals(String message, Object expected,
Object actual) {
if (equalsRegardingNull(expected, actual)) {
return;
} else if (expected instanceof String && actual instanceof String) {
String cleanMessage = message == null ? "" : message;
throw new ComparisonFailure(cleanMessage, (String) expected,
(String) actual);
} else {
failNotEquals(message, expected, actual);
}
}
private static boolean equalsRegardingNull(Object expected, Object actual) {
if (expected == null) {
return actual == null;
}
return isEquals(expected, actual);
}
private static boolean isEquals(Object expected, Object actual) {
return expected.equals(actual);
}
So as you can see it uses equals
. If you want to compare identity, you use assertSame
.
Solution 6 - Java
yes - TestNG overrides equals -
static public void assertEquals(Object actual, Object expected, String message) {
if((expected == null) && (actual == null)) {
return;
}
if(expected != null) {
if (expected.getClass().isArray()) {
assertArrayEquals(actual, expected, message);
return;
} else if (expected.equals(actual)) {
return;
}
}
failNotEquals(actual, expected, message);
}
Solution 7 - Java
In general the answer is 'yes', however unless the documentation explicitly specifies the behavior of the assertion method you should not assume that equals
is called in all cases. For example when expected == actual
or actual == null
the assertion method might return fast without calling equals
at all.
JUnit 5's Assertions
class mentions this explicitly:
> Assertion methods comparing two objects for equality, such as the assertEquals(expected, actual)
and assertNotEquals(unexpected, actual)
variants, are only intended to test equality for an (un-)expected value and an actual value. They are not designed for testing whether a class correctly implements Object.equals(Object)
. For example, assertEquals()
might immediately return true
when provided the same object for the expected and actual values, without calling equals(Object)
at all. Tests that aim to verify the equals(Object)
implementation should instead be written to explicitly verify the Object.equals(Object)
contract by using assertTrue()
or assertFalse()
— for example, assertTrue(expected.equals(actual))
, assertTrue(actual.equals(expected))
, assertFalse(expected.equals(null))
, etc.