Reputation: 1197
I'm converting a Java project into Kotlin. I've converted a User
object into Kotlin and when I run the existing JUnit tests in Java I'm getting a error between two instances of the Kotlin User
object.
User.kt:
data class User (
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
var id: Long? = null,
...
)
TestUtil.java
import static org.assertj.core.api.Assertions.assertThat;
public class TestUtil {
public static void equalsVerifier(Class clazz) throws Exception {
Object domainObject1 = clazz.getConstructor().newInstance();
// Test with an instance of the same class
Object domainObject2 = clazz.getConstructor().newInstance();
assertThat(domainObject1).isNotEqualTo(domainObject2);
}
}
The assertThat(domainObject1).isNotEqualTo(domainObject2)
test fails, as I believe in Java comparison is not done correctly on the Kotlin class. If I run this through a debugger, I can see that domainObject1
and domainObject2
are different instances.
Is it possible to get this test case to pass? The same test case is used for other Java classes, so it has to work for both Java and Kotlin classes.
Upvotes: 1
Views: 3023
Reputation: 6992
In Kotlin, equals()
is generated automatically for data class
to check for equality of the properties.
Quote from "Kotlin in Action":
The generated equals() method checks that the values of all the properties are equal. ... Note that properties that aren’t declared in the primary constructor don’t take part in the equality checks and hashcode calculation.
If you want to pass the test case without modifying it, you may override equals()
of your data class to check for referential equality.
override fun equals(other: Any?) = this === other
Note that it may affect your other code, if there is any function which relies on structural equality of your data class. So, I suggest that you refer to @shawn's answer to change your test case instead.
Upvotes: 1
Reputation: 4363
The isNotEqualTo
calls equals
. The Kotlin class implements correct equals
method for data class
. So domainObject1.equals(domainObject2)
is true. This behavior is correct.
just look at the AssertJ document:
isNotSameAs(Object other):
Verifies that the actual value is not the same as the given one,
ie using == comparison.
I think you should try:
assertThat(domainObject1).isNotSameAs(domainObject2);
Upvotes: 1