Hamcrest比较收藏品

时间:2014-02-07 10:00:07

标签: java junit hamcrest

我正在尝试比较两个列表:

assertThat(actual.getList(), is(Matchers.containsInAnyOrder(expectedList)));

但想法

java: no suitable method found for assertThat(java.util.List<Agent>,org.hamcrest.Matcher<java.lang.Iterable<? extends model.Agents>>)
method org.junit.Assert.<T>assertThat(T,org.hamcrest.Matcher<T>) is not applicable
  (no instance(s) of type variable(s) T exist so that argument type org.hamcrest.Matcher<java.lang.Iterable<? extends model.Agents>> conforms to formal parameter type org.hamcrest.Matcher<T>)
method org.junit.Assert.<T>assertThat(java.lang.String,T,org.hamcrest.Matcher<T>) is not applicable
  (cannot instantiate from arguments because actual and formal argument lists differ in length)

我该怎么写呢?

7 个答案:

答案 0 :(得分:134)

如果你想断言两个列表是相同的,不要用Hamcrest复杂化:

assertEquals(expectedList, actual.getList());

如果您真的打算执行对顺序不敏感的比较,可以调用containsInAnyOrder varargs方法并直接提供值:

assertThat(actual.getList(), containsInAnyOrder("item1", "item2"));

(假设您的列表属于String,而不是Agent,对于此示例。)

如果你真的想用List

的内容调用相同的方法
assertThat(actual.getList(), containsInAnyOrder(expectedList.toArray(new String[expectedList.size()]));

如果没有这个,你将使用单个参数调用方法,并创建一个Matcher,期望匹配Iterable,其中每个元素是{{1} }。这不能用于匹配List

也就是说,您无法将ListList<Agent>匹配,而这正是您的代码所尝试的内容。

答案 1 :(得分:48)

List<Long> actual = Arrays.asList(1L, 2L);
List<Long> expected = Arrays.asList(2L, 1L);
assertThat(actual, containsInAnyOrder(expected.toArray()));

没有冗余参数的@ Joe答案的缩短版本。

答案 2 :(得分:16)

补充@ Joe的答案:

Hamcrest为您提供了三种匹配列表的主要方法:

contains检查是否匹配计入订单的所有元素,如果列表中包含更多或更少的元素,则会失败

containsInAnyOrder检查是否匹配所有元素并且顺序无关紧要,如果列表中包含更多或更少的元素,则会失败

hasItems只检查指定的对象,如果列表中有更多

,则无关紧要

hasItem检查一个对象,如果列表中有更多

,则无关紧要

他们都可以收到一个对象列表并使用equals方法进行比较,或者可以与@borjab提到的其他匹配者混在一起:

assertThat(myList , contains(allOf(hasProperty("id", is(7L)), 
                                   hasProperty("name", is("testName1")),
                                   hasProperty("description", is("testDesc1"))),
                             allOf(hasProperty("id", is(11L)), 
                                   hasProperty("name", is("testName2")),
                                   hasProperty("description", is("testDesc2")))));

http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#contains(E...) http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#containsInAnyOrder(java.util.Collection) http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#hasItems(T...)

答案 3 :(得分:9)

使用现有的Hamcrest库(自v.2.0.0.0起),您必须在Collection上使用Collection.toArray()方法才能使用containsInAnyOrder Matcher。 更好的是将它作为一个单独的方法添加到org.hamcrest.Matchers:

libcurl

实际上我最终将这个方法添加到我的自定义测试库中并使用它来提高我的测试用例的可读性(由于更少的冗长)。

答案 4 :(得分:2)

确保列表中的Object已定义equals()。然后

    assertThat(generatedList,is(equalTo(expectedList)));

作品。

答案 5 :(得分:1)

对于对象列表,您可能需要以下内容:

x <- c('email:none@blank.com,username:noneusername, token:nonetoken21309r9023, user_id:nonuserid',
       'username:slkfsoi,email:kljasdf@asflk.com,username:oiwoie,token:asfkjsdf0',
       'email:slfkjsaf@asfdlk.com,user_id:lkasflk')

f <- function(what, string = x) {
  gsub(sprintf('%s\\:\\s*([^,]*)|.', what), '\\1', string, perl = TRUE)
}


f('email', x)
# [1] "none@blank.com"      "kljasdf@asflk.com"   "slfkjsaf@asfdlk.com"

f('username', x)
# [1] "noneusername"  "slkfsoioiwoie" ""             

f('token', x)
# [1] "nonetoken21309r9023" "asfkjsdf0"           ""                   

f('user_id', x)
# [1] "nonuserid" ""          "lkasflk"  


n <- c('email', 'username', 'token', 'user_id')
data.frame(setNames(lapply(n, f), n))

#                 email      username               token   user_id
# 1      none@blank.com  noneusername nonetoken21309r9023 nonuserid
# 2   kljasdf@asflk.com slkfsoioiwoie           asfkjsdf0          
# 3 slfkjsaf@asfdlk.com                                     lkasflk

如果您不想检查对象的顺序,请使用containsInAnyOrder

P.S。任何帮助以避免被禁止的警告将非常感激。

答案 6 :(得分:-3)

要比较保留使用的订单的两个列表,

assertThat(actualList, contains("item1","item2"));