2017-08-15 70 views
1

我正在将Java项目转换为Kotlin。我已将User对象转换为Kotlin,并且当我使用Java运行现有的JUnit测试时,我在Kotlin User对象的两个实例之间发生错误。Kotlin类实例声明不正确

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); 
    } 
} 

assertThat(domainObject1).isNotEqualTo(domainObject2)测试失败,因为我相信在Java中比较不上科特林级正确。如果我通过一个调试器运行它,我可以看到domainObject1domainObject2是不同的实例。

是否有可能让这个测试用例通过?其他Java类使用相同的测试用例,因此它必须适用于Java和Kotlin类。

+0

如果您删除'data'关键字,失败的测试将通过,这是因为Kotlin [data class](https://kotlinlang.org/docs/reference/data-classes.html#data-classes)会生成'equals'方法来比较主构造函数中的属性。 –

回答

1

isNotEqualTo调用equals。 Kotlin类为data class实施正确的equals方法。所以domainObject1.equals(domainObject2)是真的。这种行为是正确的。

只看AssertJ文件:

isNotSameAs(Object other): 
    Verifies that the actual value is not the same as the given one, 
    ie using == comparison. 

我想你应该尝试:

assertThat(domainObject1).isNotSameAs(domainObject2); 
1

在科特林,自动生成equals()data class检查属性的平等。从“科特林在行动”

引用:

生成equals()方法检查所有的属性的值是相等的。 ...请注意,未在主构造函数中声明的属性不参与平等检查和散列码计算。

如果你想通过测试用例而不修改它,你可以覆盖你的数据类的equals()来检查referential equality

override fun equals(other: Any?) = this === other 

注意,它可能会影响你的其他代码,如果有依赖于数据类的structural equality任何功能。所以,我建议你参考@ shawn的答案来改变你的测试用例。