Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我如何通过反射场比较POJO_Java_Unit Testing_Junit_Testng_Mockito - Fatal编程技术网

Java 我如何通过反射场比较POJO

Java 我如何通过反射场比较POJO,java,unit-testing,junit,testng,mockito,Java,Unit Testing,Junit,Testng,Mockito,我基本上是在寻找一个单元测试框架,我可以用它来比较不重写equals和hascode方法的pojo。我看了JUnit、Test NG和Mockito,但它们似乎没有解决问题 例如,考虑下面的代码: public class CarBean { private String brand; private String color; public CarBean (){ } public CarBean (String brand, String co

我基本上是在寻找一个单元测试框架,我可以用它来比较不重写equals和hascode方法的pojo。我看了JUnit、Test NG和Mockito,但它们似乎没有解决问题

例如,考虑下面的代码:

public class CarBean { 

    private String brand;
    private String color;

    public CarBean (){
    }

    public CarBean (String brand, String color){
        this.brand= brand;
        this.color= color;
    }

    /**
     * @return the brand
     */
    public String getBrand() {
        return brand;
    }

    /**
     * @param the brand to set
     */
    public void setBrand(String brand) {
        this.brand= brand;
    }

    /**
     * @return the color
     */
    public String getColor() {
        return color;
    }

    /**
     * @param the color to set
     */
    public void setColor(String color) {
        this.color= color;
    }
}
POJO CarBean代表了真实世界的汽车。它有两个参数,品牌和颜色。现在,假设您有两个汽车对象,如下所示:

CarBean car1 = new CarBean("Ford","Black");
CarBean car2 = new CarBean("Ford","Black");
这两个对象具有相同的参数值。但当您使用equals进行比较时,它返回false:

car1.equals(car2); // This returns false
现在我需要单元测试一个返回CarBean对象的方法。在这个场景中,我要么需要逐个比较carbean属性,要么需要实现equals()和hashcode()方法


所以我的问题是——已经有一个单元测试框架可以处理这个问题了吗?

,因为这可能是使用反射实现的。“反射等于”是一个合理的搜索词,谷歌发现:


没有什么能阻止你写自己的比较

使用JUnit:

编写一个静态方法,该方法接受2个对象并执行所需的断言:

public static void sameBrandAndColor(Car expected, Car actual){
     assertEquals(expected.getBrand(), actual.getBrand());
     assertEquals(expected.getColor(), actual.getColor());
}
然后在测试中,只需调用比较方法即可

@Test
public void test(){
    ...
    sameBrandAndColor(car1, car2);
}

这种类型的反射内置于Hamcrest as中,它比较bean命名的属性(getFoo、isBar),而不是可能为它们提供动力的字段。核心Hamcrest支持内置于JUnit中,因此您只需添加包含SamePropertyValuesAs matcher的Hamcrest库

assertThat(car1, samePropertyValuesAs(car2));

Unitils似乎确实解决了我的问题。以下API可以反射地比较对象。即使POJO本身的属性是用户定义的POJO,也可以进行比较:

import static org.unitils.reflectionassert.ReflectionAssert.*;

// Exact field-by-field comparison
assertReflectionEquals(new Person("John", "Doe", new Address("New street", 5, "Brussels")), 
                                 new Person("John", "Doe", new Address("New street", 5, "Brussels"));

// Ignore Null / 0 values in the expected object
assertReflectionEquals(new Person("John", null, new Address("New street", 0, null)),
                                 new Person("John", "Doe", new Address("New street", 5, "Brussels"), 
                                 ReflectionComparatorMode.IGNORE_DEFAULTS); 

// Ignore collection order
assertReflectionEquals(Arrays.asList(new Person("John"), new Person("Jane")),
                                 new Person[] {new Person("Jane"), new Person("John")}, 
                                 ReflectionComparatorMode.LENIENT_ORDER);

// Ignore null/0 values + collection order
assertLenientEquals(Arrays.asList(new Person("John"), null),
                                 new Person[] {new Person("Jane", "Doe"), new Person("John", "Doe")});

// Check only the firstName property 
assertPropertyLenientEquals("firstName", Arrays.asList("John", "Jane"),
                                 new Person[] {new Person("Jane", "Doe"), new Person("John", "Doe")});
有关详细信息,请参见

在pojo类中重写toString()方法,如下所示

@Override
public String toString() {
    return "brand: " + this.brand + ",color: " + this.color;
}


car1.toString().equals(car2.toString()); //It will return true if both objects has same values
如果你有大量的参数,我建议你使用下面的代码

public static boolean comparePOJO(Object obj1, Object obj2) {
    return new Gson().toJson(obj1).equals(new Gson().toJson(obj2));
}
comparePOJO(car1,car2); //It will return true

你想看看推土机……你可能想重新表述这个问题。“我如何能通过它们的字段反射性地比较POJO”很可能是该站点的主题,但明确要求提供框架并不是该站点的主题。也就是说,快速搜索也不会得到很好的主题答案,所以这个问题可能对未来的用户有用,只需进行一些编辑。谢谢@JeffBowman。如果您发现它对您的目的有用,您可能会使用apache的commons EqualsBuilder.reflectionEquals(这个,obj);很明显,但我想要的是减少手动工作并使事情自动化。在这种情况下,只有3行代码。这不需要太多的手工工作,而且可以显示意图。是的,上面的代码只有3行。但在我的应用程序中,POJO将有50多个属性,其中一些是另一个具有类似属性计数的POJO。谢谢。这有点接近我要找的。让我进一步探讨这个框架。