mockito 如何测试两个不同的对象具有相同的值

flvlnr44  于 11个月前  发布在  其他
关注(0)|答案(5)|浏览(138)

我正在用Mockito和JUnit为我的代码编写测试。到目前为止一切都很好,但知道我有StackOverFlow错误。我想,我得到那个错误是因为我的对象是嵌套的。例如,A对象与B对象有关系,B对象也与A对象有关系。
我正在测试我的对象是否具有相同的值

assertEquals(objectA.toString(), objectB.toString());

字符串
我想从我的两个对象中删除@ToString注解来处理StackOverFlow错误,但我不知道如何测试两个不同的对象是否相等。我在这里看到了一些主题,他们告诉使用assertThat,但我也没有。
我如何测试两个不同对象的值是否相同?如果你有其他的解决办法,我也想听听。

zengzsys

zengzsys1#

重写equals方法并使用assertEquals:您可以重写对象中的equals方法,以比较相关字段是否相等。然后,您可以使用assertEquals来比较整个对象。
举例来说:

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null || getClass() != obj.getClass()) {
        return false;
    }
    ObjectA other = (ObjectA) obj;
    return Objects.equals(field1, other.field1) &&
           Objects.equals(field2, other.field2) &&
           // Repeat for other fields
}

// In your test
assertEquals(objectA, objectB);

字符串

dy2hfwbg

dy2hfwbg2#

我认为Kedar Thakkar的答案应该有效,而且应该这样做,但是如果你仍然遇到无限递归问题,那么你可以单独检查你想要比较的每个字段。你可以写一个方法,接受两个对象,如果它们的值相等,则返回,例如:

public boolean compareFields(Object objectA, Object objectB) {

  if (objectA == objectB) return true;

  if (objectA == null && objectB == null) return true; // depends, do you want two null objects to be treated as equal? If not, use || instead and delete the following line

  if (objectA == null ^ objectB == null) return false;

  return objectA.field1.equals(objectB.field1) &&
         objectA.field2.equals(objectB.field2) &&
         objectA.field3 == objectB.field3 && // in case it's a primitive type
         // and so on
}

字符串
显然,您应该将在方法参数中引入的类类型从Object更改为您想要比较的特定类。
然后你可以Assert这个方法的结果:

assertTrue(compareFields(objectA, objectB));

wbgh16ku

wbgh16ku3#

您可以使用equal(Object object)hashCode()来实现:

@Override
    public int hashCode() {
        int hash = 0;
        hash += (fieldName != null ? fieldName.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof ClassName)) {
            return false;
        }
        ClassName other = (ClassName) object;
        if ((this.fieldName == null && other.fieldName != null) || (this.fieldName != null && !this.fieldName.equals(other.fieldName))) {
            return false;
        }
        return true;
    }

字符串
hashCode()是本机方法,返回对象的整数哈希代码值。
hashCode()的实现可以使用您希望使用的字段来完成。如果两个或多个对象的hashCodes匹配,则它们是相同的,这意味着应该获得相同的int值,以便告诉对象是相同的。

vxqlmq5t

vxqlmq5t4#

你需要写一个非递归的equals方法。
假设你的类看起来像:

class A {
    String name;
    B b;
}

class B {
    String name;
    A a;
}

字符串
为了简洁起见,我只使用字段--您应该使用私有字段和getter来编写这些字段。
equals/hashcode看起来像:

class A {
  ...
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        B b = (B) o;
        return Objects.equals(name, b.name) && Objects.equals(a.name, b.a.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, a.name);
    }
}


移除递归。B需要同样的处理。
当然,拥有这种关系意味着,如果在B中添加或删除字段,则需要更改Aequals/hashcode实现。
如果你知道(因为你构造A和B示例的方式)x.equals(y)意味着x == y适用于AB的所有示例,那么你可以通过使用引用相等来简化你的实现。

rmbxnbpk

rmbxnbpk5#

首先,谢谢你们大家。我有太多的对象和属性。因此,您的建议需要对源代码进行大量更改。我不想在我测试我的服务时做这个。我在here中发现了类似的问题。我修复了@ToString.Exclude注解的问题。

相关问题