2014-12-05 70 views
10

我基本上寻找一个单元测试框架,我可以用它来比较POJOs不覆盖等于和hascode方法。我看了一下JUnit,Test NG和Mockito,但他们似乎并没有解决这个问题。我怎样才能比较POJO他们的领域反射

例如,考虑下面的代码:

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()方法。

所以我的问题是 - 是否已经有一个单元测试框架,可以处理这个?

+0

你想看看推土机... – 2014-12-06 00:04:51

+0

你可能想要重述这个问题。“我如何才能比较POJO的字段反映”可能是关于该网站的主题,但根据[本FAQ的第4项],明确要求框架不在主题上(http://stackoverflow.com/帮助/切合主题)。也就是说,快速搜索不会产生任何好的主题答案,所以这个问题可能对未来的用户有一定的帮助。 – 2014-12-06 18:41:47

+0

谢谢@JeffBowman。有意义 – 2014-12-06 23:16:25

回答

4

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

Unitils Cookbook

-2

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

使用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); 
} 
+0

很明显,但我正在寻找的是减少手动工作和自动化的东西 – 2014-12-06 05:41:51

+0

它只有3行代码在这种情况下。这不是太多的人工努力,并意图揭示。 – dkatzel 2014-12-06 05:43:25

+0

是的,上面的代码只有3行。但在我的应用程序中,pojos会有50个以上的属性,其中一些属性是具有相似属性计数的另一个pojos。 – 2014-12-06 05:46:17

2

这种类型的反射的内置Hamcrest作为SamePropertyValuesAs,其比较豆命名属性(的getFoo,isBar)代替该可能它们供电的字段。 Core Hamcrest支持内置于JUnit中,因此您只需添加包含SamePropertyValuesAs匹配器的Hamcrest库。

assertThat(car1, samePropertyValuesAs(car2)); 
2

重写ToString()方法的更多信息,你的POJO类像下面

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


car1.toString().equals(car2.toString()); //It will return true 

如果你有大数量的参数,我会建议你去下面的代码

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