代码之家  ›  专栏  ›  技术社区  ›  Subhomoy Sikdar

在单元测试中比较两个对象中的所有属性

  •  -1
  • Subhomoy Sikdar  · 技术社区  · 6 年前

    我有一些对象(属于不同的类)比如PersonType1和PersonType2,并试图比较测试用例中的字段是否相等。场景如下:

    jsonA -> PersonTypeA;
    jsonB -> PersonTypeB;
    

    我试图断言这些值是相等的,如下所示:

    assertEquals(personA.getId(), personB.getId());
    

    我不打算写一堆额外的代码来比较obejcts。更重要的是:

    Assert.assertTrue(new ReflectionEquals(expected, excludeFields).matches(actual)); //mockito
    

    Assert.assertTrue(compareProperties(expected, excludeFields).matches(actual));
    

    这不是重复的问题 我想比较一下 如果它们在具有相同名称的属性中具有相同的值。我可以编写代码,但如果junit5、mockito、hamcrest等中已经存在一些现有的util方法,则可以查找这些方法

    assertEquals(objA.getId(), objB.getId());
    //like this there are 30 properties
    

    还有一些嵌套对象,比如list,set of string。手动比较它们太痛苦了

    编辑2:也许这能更好地解释

    我无法控制波乔河。他们是别人的。基本上,如果我有两门课

    class Cat{
      String id;
      String name;
      // 30 more properties
    }
    
    class Dog{
      String id;
      String name;
     // 30 more properties
    }
    

    assertEquals(cat.getId(), dog.getId());
    

    那么,有什么实用工具可以做到这一点吗?我们可以反过来做,如果我们有两个对象(属于不同的类),我们可以使用 BeanUtils.copyProperies(o1, o2) 在春天和阿帕奇的豆子实用程序。同样地,是否有方法比较这些属性?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Mark Bramnik    6 年前

    实现这一目标的方法有很多,举几个例子:

    选择1

    assertThat(actual, MyMatchers.semanticallyEqualsTo(expected));
    

    选择2

    选择3

    提供一种转换器方法:

    class PersonTypeA {
       public PersonTypeB asTypeB() {
         ... if it has same properties, the conversion is trivial
         return new PersonTypeB   
       }
    }
    

    然后在测试中使用此方法,以便预期的和实际的类型相同,并且可以使用 assertEquals

    提供某种类型的“两个对象的公共表示”。您已经提到它们与JSON有某种关联,因此您可能可以将这两个值都表示为某种JSON:

     class PersonTypeA {
        public JSONObject toJson() {...}
     }
    
     class PersonTypeB {
        public JSONObject toJson();
     }
    

    jsonassert

    笔记: 选项3和4也可以“外部”实现 PersonTypeA PersonTypeB 在一些实用类中。

    但从技术上来说所有的选择都是有效的

        2
  •  0
  •   Subhomoy Sikdar    6 年前

    对于相同的类对象比较,我们可以使用如下的Mockito ReflectionEquals。按链接查找原始答案

    assertTrue(new ReflectionEquals(deployments.get(0)).matches(returnedDeployments.get(0)));
    

    https://stackoverflow.com/a/29793460/3497657

    我看到了,因为ReflectionEquals是一个内部类,所以最好使用Hamcrest samepropertyvalues,如下所示:

    assertThat(returnedDeployments.get(0), samePropertyValuesAs(deployments.get(0)));
    

    public class HasSameProperties<T> extends TypeSafeDiagnosingMatcher<T> {
      private ClassA obj1;
    
      public HasSameProperties(ClassA obj1) {
        this.obj1 = obj1;
      }
    
      @Override
      protected boolean matchesSafely(T item, Description mismatchDescription) {
         if (item instanceof ClassA)
           return matchClassA((ClassA) item);
    
         return null;
      }
    
      public static Matcher<ClassB> hasSameProperties(ClassA objA) {
        return new HasSameProperties(objA);
      }
    
      private boolean matchClassA(ClassB objB) {
        assertThat(objB.getId(), equalTo(objA.getId()));
        //other getters and setters
        return true;
      }