2016-02-26 66 views
5

我有相当复杂的对象结构(带有一堆原始字段和对象引用),并且想要测试除-a部分之外的所有字段。举个例子;Hamcrest - 优雅的方式来测试具有相同propertyity值的复杂对象

ComplexObject actual = generateMagically("someInput"); 
ComplexObject expected = ActualFunction.instance.workMagically(actual); 

// we want to be sure that workMagically() would create a new ComplexObject 
// with some fields are different than "actual" object. 

// assertThat(actual, samePropertyValuesAs(expected)); would check all fields. 
// what I want is actually; - notice that "fieldName1" and "fieldName2" are 
// primitives belong to ComplexObject 
assertThat(actual, samePropertyValuesExceptAs(expected, "fieldName1", "fieldName2")) 

由于我不想手动检查所有字段,我相信必须有一种方法来优雅地编写测试。有任何想法吗?

干杯。

+0

所以,你有两个袋* *的对象,想进行深度比较呢? – Raffaele

+0

不确定要叫他们包对象,有许多原始字段和其他对象引用。我想跳过的字段是属于ComplexObject的原始字段。我们可以说这将是一个深刻的比较。 – tugcem

+0

你是否只想''samePropertyValuesExceptAs'的Matcher实现作为这个问题的答案?如果是这样的话,你可以创建'org.hamcrest.beans.SamePropertyValuesAs '的副本,并添加另一个构造函数/静态工厂方法,该方法将删除被排除的属性进行测试。 – SpaceTrucker

回答

0

一般来说,我看到两个解决方案,如果ComplexObject可以自己修改。

您可以引入一个界面,该界面代表ActualFunction正在更改的ComplexObject的属性。然后您可以测试该新界面的所有属性都已更改。这将需要ComplexObject实现该新界面。

另一种方法是用包含所有这些属性的新类型的新属性替换ActualFunction更改的ComplextObject的属性。那么更好的设计就是让ActualFunction返回新类型的一个实例。

+0

Thanks SpaceTrucker。(1 )我认为在域对象中实现一个接口仅仅用于测试目的不是最佳实践。(2)对于另一种方法,您实际上提供了添加一个新属性(我假设有一个新对象),它已经更新了属性?再次改变对象只是为了测试,我猜不。 – tugcem

+0

@tugcem这不仅是关于测试,而是关于使'ActualFunction'的效果更加明显,而且它所表示的功能更具表现力。例如,如果“ActualFunction”的实现将改变为也修改另一个属性,那么如果使用我的第二种方法,因为新类型将获得该新属性,则此效果将立即可见。 – SpaceTrucker

+0

我实际上并不需要在workMagically()函数中添加额外的表达式或可见性来更改属性。事实上,我们不想对更新字段做任何明确的说明,并期望这个类的用户意识到这一点。 – tugcem

0

上次我有类似的要求我得出的结论是,手动编写代码和测试以断言某些值更新本身就很容易且容易出错。

我将包对象中的字段外化,并在编译时为包类本身和复制器生成Java源文件。通过这种方式,您可以测试实际的代码(生成器),并在一个地方准确定义域的实际定义,以便复制代码不会过时。

描述该属性可以是任何东西,你是舒服,从JSON-架构XML和Java本身(Java示例如下 - 自定义的注释是从发电机消耗)语言

public class MyBag { 
    @Prop public int oh; 
    @Prop public String yeah; 
} 
7

你应该看看shazamcrest,一个很棒的Hamcrest扩展,它提供了你所需要的。

assertThat(expected, sameBeanAs(expectedPerson).ignoring("fieldName1").ignoring("fieldName2")); 

https://github.com/shazam/shazamcrest#ignoring-fields

+1

如果有人想知道'''sameBeanAs''在哪里,它在 '''com.shazam.shazamcrest.matcher.Matchers''类中。 –

相关问题