Rya*_*son 82 java junit unit-testing
假设我有一个没有equals()方法的类,没有源.我想在该类的两个实例上断言相等.
我可以做多个断言:
assertEquals(obj1.getFieldA(), obj2.getFieldA());
assertEquals(obj1.getFieldB(), obj2.getFieldB());
assertEquals(obj1.getFieldC(), obj2.getFieldC());
...
Run Code Online (Sandbox Code Playgroud)
我不喜欢这个解决方案,因为如果早期的断言失败,我就不会得到完全相等的图片.
我可以自己手动比较并跟踪结果:
String errorStr = "";
if(!obj1.getFieldA().equals(obj2.getFieldA())) {
errorStr += "expected: " + obj1.getFieldA() + ", actual: " + obj2.getFieldA() + "\n";
}
if(!obj1.getFieldB().equals(obj2.getFieldB())) {
errorStr += "expected: " + obj1.getFieldB() + ", actual: " + obj2.getFieldB() + "\n";
}
...
assertEquals("", errorStr);
Run Code Online (Sandbox Code Playgroud)
这给了我完全平等的图片,但是很笨重(我甚至没有考虑到可能的零问题).第三种选择是使用Comparator,但compareTo()不会告诉我哪些字段失败相等.
有没有更好的做法从对象获得我想要的东西,没有子类化和覆盖equals(ugh)?
fel*_*age 50
Mockito提供了一个反射匹配器:
Assert.assertTrue(new ReflectionEquals(expected, excludeFields).matches(actual));
Run Code Online (Sandbox Code Playgroud)
Abh*_*she 41
我通常使用org.apache.commons.lang3.builder.EqualsBuilder实现这个用例
Assert.assertTrue(EqualsBuilder.reflectionEquals(expected,actual));
Run Code Online (Sandbox Code Playgroud)
Tho*_*mas 34
这里有很多正确的答案,但我也想添加我的版本.这是基于Assertj.
import static org.assertj.core.api.Assertions.assertThat;
public class TestClass {
public void test() {
// do the actual test
assertThat(actualObject)
.isEqualToComparingFieldByFieldRecursively(expectedObject);
}
}
Run Code Online (Sandbox Code Playgroud)
lop*_*vit 12
我知道它有点旧,但我希望它有所帮助.
我遇到了与你相同的问题,因此,在调查之后,我发现了几个与此问题相似的问题,并且在找到解决方案之后,我在回答这些问题,因为我认为它可以帮助其他人.
这个类似问题的最多投票答案(不是作者选择的答案)是最合适的解决方案.
基本上,它包括使用名为Unitils的库.
这是用途:
User user1 = new User(1, "John", "Doe");
User user2 = new User(1, "John", "Doe");
assertReflectionEquals(user1, user2);
Run Code Online (Sandbox Code Playgroud)
即使该类User没有实现,它也会通过equals().您可以assertLenientEquals在他们的教程中看到更多示例和一个非常酷的断言.
由于这个问题很旧,我将建议使用 JUnit 5 的另一种现代方法。
我不喜欢这个解决方案,因为如果早期断言失败,我就无法获得完整的平等图。
在 JUnit 5 中,有一种方法Assertions.assertAll()可以让您将测试中的所有断言分组在一起,并且它将执行每个断言并在最后输出任何失败的断言。这意味着任何先失败的断言都不会停止后面断言的执行。
assertAll("Test obj1 with obj2 equality",
() -> assertEquals(obj1.getFieldA(), obj2.getFieldA()),
() -> assertEquals(obj1.getFieldB(), obj2.getFieldB()),
() -> assertEquals(obj1.getFieldC(), obj2.getFieldC()));
Run Code Online (Sandbox Code Playgroud)
您可以使用Apache commons lang ReflectionToStringBuilder
您可以指定要逐个测试的属性,也可以更好地排除您不想要的属性:
String s = new ReflectionToStringBuilder(o, ToStringStyle.SHORT_PREFIX_STYLE)
.setExcludeFieldNames(new String[] { "foo", "bar" }).toString()
Run Code Online (Sandbox Code Playgroud)
然后,您可以正常比较两个字符串.关于反射速度慢的问题,我认为这仅用于测试,因此不应该如此重要.
如果您在断言(assertThat)中使用hamcrest,并且不想引入其他测试库,则可以SamePropertyValuesAs.samePropertyValuesAs断言没有覆盖equals方法的项目。
好处是,您不必引入另一个测试框架,并且当assert失败(expected: field=<value> but was field=<something else>)时(而不是expected: true but was false使用类似的东西),它将给出一个有用的错误EqualsBuilder.reflectionEquals()。
缺点是比较浅,没有选择排除字段的选项(例如EqualsBuilder中的字段),因此您必须解决嵌套对象(例如,删除它们并独立比较它们)。
最佳情况:
import static org.hamcrest.beans.SamePropertyValuesAs.samePropertyValuesAs;
...
assertThat(actual, is(samePropertyValuesAs(expected)));
Run Code Online (Sandbox Code Playgroud)
丑案:
import static org.hamcrest.beans.SamePropertyValuesAs.samePropertyValuesAs;
...
SomeClass expected = buildExpected();
SomeClass actual = sut.doSomething();
assertThat(actual.getSubObject(), is(samePropertyValuesAs(expected.getSubObject())));
expected.setSubObject(null);
actual.setSubObject(null);
assertThat(actual, is(samePropertyValuesAs(expected)));
Run Code Online (Sandbox Code Playgroud)
所以,选择你的毒药。其他框架(例如Unitils),无用的错误(例如EqualsBuilder)或浅比较(hamcrest)。
Enr*_*tín -6
您可以重写类的 equals 方法,例如:
@Override
public int hashCode() {
int hash = 0;
hash += (app != null ? app.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
HubRule other = (HubRule) object;
if (this.app.equals(other.app)) {
boolean operatorHubList = false;
if (other.operator != null ? this.operator != null ? this.operator
.equals(other.operator) : false : true) {
operatorHubList = true;
}
if (operatorHubList) {
return true;
} else {
return false;
}
} else {
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,如果你想比较一个类中的两个对象,你必须以某种方式实现 equals 和 hash code 方法
| 归档时间: |
|
| 查看次数: |
74048 次 |
| 最近记录: |