如果我有两个来自如下两个不同类的示例(具有相似的属性),我可以使用hamcrest的吗 containsInAnyOrder
去匹配他们的属性?
class Something{
int id;
int name;
}
class GsonSomething{
int id;
int name;
}
我能用吗 containsInAnyOrder
或者其他方法来比较两个类中的两个列表?
List<Something> somethingList; //[ {id:1, name: "one"}, {id:1, name: "two"} ]
List<GsonSomething> gsonSomethingList; //[ {id:1, name: "one"}, {id:1, name: "two"} ]
在测试方法中使用这个用例来比较结果和预期结果。我采用了以下方法:
for(Something s : somethingList){
GsonSomething gs = gsonSomethingList.stream().filter(p -> p.id.equals(s.id)).findFirst();
assertEquals(s.name, gs.name);
//assert other attributes
}
3条答案
按热度按时间r55awzrz1#
通过扩展http://hamcrest.org/javahamcrest/javadoc/1.3/org/hamcrest/basematcher.html 并在Assert中使用它。
pvabu6sv2#
不是直接的,不是。
为什么不呢?
java认为类型名称空间是神圣的,其他的一切只与它所在的类型有关。换句话说,在java中,这两种方法:
被认为是完全不相关的,而恰好具有相同名称的字段也是如此:并不意味着它们是相关的。
好吧,那我该怎么做?
你得千方百计把你的输入转化成可以比较的东西。
幸运的是,这相对简单。如果它是你想要比较的单一属性(比如
int id
值),然后将两个值都转换为该值,然后运行比较。如果你有“复合键”(你想要两者)
id
以及name
你需要一种能装下这些钥匙的类型。可能两者都有GsonSomething
以及Something
他们自己是合格的类型,可以做这项工作,所以你真的只需要转换,比方说,你的列表GsonSomething
一份Something
然后你可以比较。但我的解决方案呢
你的解决方案有两个问题。
最明显的一点是:它做得不好。如果gsonsomethinglist中有一个元素根本没有出现在somethinglist中,那么您的测试仍然会通过,这是不正确的。
一个问题稍小的问题是:它非常慢;是o(n^2)速度。如果输入开始达到5位数(10k或更高-在这个范围内),你会注意到。一旦他们达到7,这个测试就要花很长时间。
那么什么是更好的方法呢?
为了加速比较,需要将它们放在一个集合中,这需要适当的equals和hashcode impl。让我们从这里开始
Something
记录类别:如果Lombok山不是你正在使用的东西,也许:
现在我们有了这些,我们可以将一个转换成另一个,并使用集合,它可以更快地完成这样的工作(实际上,算法上是这样):
现在你可以用containsinanyorder和
a
以及b
.tvmytwxo3#
我会做一些轻微的重构。我首先创建一个基类
Something
以及GsonSomething
班级扩展。在基类中,我将重写equals
方法。现在,这很简单。你的两个
List
字段现在将是:对hamcrest方法的简单调用应该可以完成这项工作: