我认为这应该是一个非常简单的问题.但不知何故,我无法在谷歌找到答案.
假设我有2个字符串列表.首先包含"字符串A"和"字符串B",第二个包含"字符串B"和"字符串A"(按顺序通知差异).我想用JUnit测试它们以检查它们是否包含完全相同的字符串.
是否有任何断言检查忽略顺序的字符串的相等性?对于给定的示例org.junit.Assert.assertEquals抛出AssertionError
java.lang.AssertionError: expected:<[String A, String B]> but was:<[String B, String A]>
Run Code Online (Sandbox Code Playgroud)
解决方法是首先对列表进行排序,然后将它们传递给断言.但我希望我的代码尽可能简单和干净.
我使用Hamcrest 1.3,JUnit 4.11,Mockito 1.9.5.
Hamcrest提供了许多用于断言集合内容的匹配器.所有这些案件都通过:
Collection<String> c = ImmutableList.of("one", "two", "three");
assertThat(c, hasItems("one", "two", "three");
assertThat(c, contains("one", "two", "three");
assertThat(c, containsInAnyOrder("one", "two", "three");
Run Code Online (Sandbox Code Playgroud)
如何hasItems
,contains
以及containsInAnyOrder
有什么不同?
如果给定的集合包含给定顺序的给定项目,如何使用Hamcrest进行检查?我试过hasItems
但它只是忽略了顺序.
List<String> list = Arrays.asList("foo", "bar", "boo");
assertThat(list, hasItems("foo", "boo"));
//I want this to fail, because the order is different than in "list"
assertThat(list, hasItems("boo", "foo"));
Run Code Online (Sandbox Code Playgroud) 假设我有一张地图:
Map<String,Object> map1 = new HashMap<String,Object>();
map1.put("foo1","foo1");
map1.put("foo2", Arrays.asList("foo2","bar2"));
Run Code Online (Sandbox Code Playgroud)
现在我想使用Hamcrest匹配器来验证Map的值.如果这是一个Map <String,String>我会做类似的事情:
assertThat(map1, hasEntry("foo1", "foo1"));
Run Code Online (Sandbox Code Playgroud)
但是,我试图在Map中使用它时遇到困难,Map中的条目可能是String或值列表.这适用于第一个条目:
assertThat(map1, hasEntry("foo1", (Object)"foo1"));
Run Code Online (Sandbox Code Playgroud)
对于第二个条目,我无法弄清楚如何设置Matchers.
编辑:
我也尝试了这个,但它会产生编译器警告.
assertThat(
map1,
hasEntry(
"foo2",
contains(hasProperty("name", is("foo2")),
hasProperty("name", is("bar2")))));
Run Code Online (Sandbox Code Playgroud)
"Assert类型中的方法assertThat(T,Matcher)不适用于参数(Map,Matcher >>>)"
(以上是解决方案:Hamcrest比较收藏)
我正在使用Hamcrest 1.3并试图以更紧凑的方式实现以下目标.
考虑以下测试用例:
@Test
public void testCase() throws Exception {
Collection<String> strings = Arrays.asList(
"string one",
"string two",
"string three"
);
// variant 1:
assertThat(strings, hasSize(greaterThan(2)));
assertThat(strings, hasItem(is("string two")));
// variant 2:
assertThat(strings, allOf(
hasSize(greaterThan(2)),
hasItem(is("string two"))
));
}
Run Code Online (Sandbox Code Playgroud)
这里的目标是检查集合的大小和要包含的一些特定项目.
在第一种变化是可能的并且被接受的情况下,这并不总是那么容易,因为集合本身可能是其他一些操作的结果,因此使用allOf
操作对其进行所有操作更有意义.这是在上面的第二个变体中完成的.
但是,包含第二个变体的代码将导致以下编译时错误:
error: no suitable method found for allOf(Matcher<Collection<? extends Object>>,Matcher<Iterable<? extends String>>)
Run Code Online (Sandbox Code Playgroud)
实际上是否有任何特定的方法来测试Hamcrest中使用单次操作(例如allOf
)的集合的大小和项目?
如果可以按任何顺序退回产品,您会如何重构以下内容?
List<Product> products = get_products("test_produc");
assertEquals(products.size(),3);
assertEquals(products.get(0).getName(), "test_product1");
assertEquals(products.get(1).getName(), "test_product2");
assertEquals(products.get(2).getName(), "test_produc3");
Run Code Online (Sandbox Code Playgroud)
如果可以使用流优雅地完成,那么我就开始提出这些建议.Hamcrest的建议也很受欢迎.
我正在使用这个依赖项:
<dependencies>
<!-- Testing -->
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
Run Code Online (Sandbox Code Playgroud)
但是,使用如下函数:
List<String> output = ..;
List<String> data = ...;
Assert.assertThat(output, Matchers.containsInAnyOrder(data));
Run Code Online (Sandbox Code Playgroud)
结果出错。修复 hamcrest 以便该功能真正发挥作用的正确方法是什么?我尝试找出正确的依赖管理并找到了上面提到的配置。
我收到的错误是断言错误,如果我比较两个相同的列表但具有已打乱的值,它不会通过但会失败
例子:
List<String> output = Arrays.asList(
"text1\t1",
"text2\t1",
"text3\t1",
"text4\t1",
"text5\t1",
"text6\t1",
"text7\t1",
"text8\t1", …
Run Code Online (Sandbox Code Playgroud) 我有两个集合,我试图在单元测试中比较相等,但我正在努力使用contains方法.这是我有的:
@Test
public void getAllItems() {
Collection<Item> actualItems = auction.getAllItems(joe);
Collection<Item> expectedItems = Lists.newArrayList();
expectedItems.add(iPhone);
expectedItems.add(skateboard);
assertThat(expectedItems, contains(actualItems));
}
Run Code Online (Sandbox Code Playgroud)
items
包含相同的对象,expectedItems
所以我希望断言是真的,但这是我得到的输出:
[Item{name=iPhone}, Item{name=Skateboard}] --> Expected
[Item{name=iPhone}, Item{name=Skateboard}] --> Actual
java.lang.AssertionError:
Expected: iterable containing [<[Item{name=iPhone}, Item{name=Skateboard}]>]
but: item 0: was <Item{name=iPhone}>
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
Run Code Online (Sandbox Code Playgroud)
请问我在使用该contains
方法出错的地方帮助我?
public class Item {
private String name;
public Item(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} …
Run Code Online (Sandbox Code Playgroud)