使用 assertThat 测试列表列表是否包含特定元素
Test if list of lists contains specific element using assertThat
我尝试使用 Assert#assertThat
检查列表列表中的每个列表是否包含特定值。
我写了这段代码,但它不起作用。
测试未编译,代码带有红线下划线并显示错误消息(查看注释):
List<List<String>> testedList = new ArrayList<>();
List<String> firstList = new ArrayList<>();
firstList.add("1");
firstList.add("2");
List<String> secondList = new ArrayList<>();
secondList.add("2");
secondList.add("3");
testedList.add(firstList);
testedList.add(secondList);
Assert.assertThat(testedList, CoreMatchers.everyItem(CoreMatchers.hasItem("2")));
// Required type Provided
// actual: T List<java.util.List<java.lang.String>>
// matcher: Matcher<? super T> Matcher<Iterable<Iterable<? super String>>>
甚至使用显式类型:
Assert.assertThat(testedList, CoreMatchers.<List<String>>everyItem(CoreMatchers.<String>hasItem("2")));
// Required type: Matcher<List<String>>
// Provided: Matcher<Iterable<? super String>>
如果它只是字符串列表,我可以检查每个字符串是否包含特定的字母:
List<String> testedList = new ArrayList<>();
testedList.add("1a");
testedList.add("2a");
Assert.assertThat(testedList, CoreMatchers.everyItem(CoreMatchers.containsString("a")));
那么我的代码有什么问题?
我该如何解决?
进口:
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
import java.util.ArrayList;
Gradle 依赖关系:
testCompile group: 'junit', name: 'junit', version: '4.12'
希望对您有所帮助,我尝试了另一种搜索元素的方法。我使用嵌套的 foreach 循环来查看列表列表是否包含该特定元素。
List<List<String>> testedList = new ArrayList<>();
boolean exist = false;
List<String> firstList = new ArrayList<>();
firstList.add("1");
firstList.add("2");
List<String> secondList = new ArrayList<>();
secondList.add("2");
secondList.add("3");
testedList.add(firstList);
testedList.add(secondList);
for(List <String> e : testedList){
for(String i : e){
if(i.equalsIgnoreCase("2"))
exist = true;
}
}System.out.println(exist);`
我认为 everyItem
匹配器不是为 hasItem
设计的,你已经发现你陷入了泛型地狱。
除了定义一个将“封装”泛型限制并将委托给 hasItem
匹配器的匹配器之外,我没有看到一个简单的解决方案。幸运的是,定义一个新的匹配器确实是一件容易的事。看看:
private class HasItemMatcher<T> extends BaseMatcher<List<T>> {
private final Matcher<Iterable<? super T>> iterableMatcher;
public HasItemMatcher(T value) {
this.iterableMatcher = CoreMatchers.hasItem(value);
}
@Override
public boolean matches(Object item) {
return iterableMatcher.matches(item);
}
@Override
public void describeTo(Description description) {
iterableMatcher.describeTo(description);
}
}
这段代码是不言自明的。它将所有工作委托给现有的匹配器。
考虑到这一点,您可以将测试重写为:
@Test
public void sampleTest() {
List<List<String>> testedList = new ArrayList<>();
List<String> firstList = new ArrayList<>();
firstList.add("1");
firstList.add("2");
List<String> secondList = new ArrayList<>();
secondList.add("2");
secondList.add("3");
testedList.add(firstList);
testedList.add(secondList);
Assert.assertThat(testedList, CoreMatchers.everyItem(new HasItemMatcher<>("2")));
}
我尝试使用 Assert#assertThat
检查列表列表中的每个列表是否包含特定值。
我写了这段代码,但它不起作用。 测试未编译,代码带有红线下划线并显示错误消息(查看注释):
List<List<String>> testedList = new ArrayList<>();
List<String> firstList = new ArrayList<>();
firstList.add("1");
firstList.add("2");
List<String> secondList = new ArrayList<>();
secondList.add("2");
secondList.add("3");
testedList.add(firstList);
testedList.add(secondList);
Assert.assertThat(testedList, CoreMatchers.everyItem(CoreMatchers.hasItem("2")));
// Required type Provided
// actual: T List<java.util.List<java.lang.String>>
// matcher: Matcher<? super T> Matcher<Iterable<Iterable<? super String>>>
甚至使用显式类型:
Assert.assertThat(testedList, CoreMatchers.<List<String>>everyItem(CoreMatchers.<String>hasItem("2")));
// Required type: Matcher<List<String>>
// Provided: Matcher<Iterable<? super String>>
如果它只是字符串列表,我可以检查每个字符串是否包含特定的字母:
List<String> testedList = new ArrayList<>();
testedList.add("1a");
testedList.add("2a");
Assert.assertThat(testedList, CoreMatchers.everyItem(CoreMatchers.containsString("a")));
那么我的代码有什么问题? 我该如何解决?
进口:
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
import java.util.ArrayList;
Gradle 依赖关系:
testCompile group: 'junit', name: 'junit', version: '4.12'
希望对您有所帮助,我尝试了另一种搜索元素的方法。我使用嵌套的 foreach 循环来查看列表列表是否包含该特定元素。
List<List<String>> testedList = new ArrayList<>();
boolean exist = false;
List<String> firstList = new ArrayList<>();
firstList.add("1");
firstList.add("2");
List<String> secondList = new ArrayList<>();
secondList.add("2");
secondList.add("3");
testedList.add(firstList);
testedList.add(secondList);
for(List <String> e : testedList){
for(String i : e){
if(i.equalsIgnoreCase("2"))
exist = true;
}
}System.out.println(exist);`
我认为 everyItem
匹配器不是为 hasItem
设计的,你已经发现你陷入了泛型地狱。
除了定义一个将“封装”泛型限制并将委托给 hasItem
匹配器的匹配器之外,我没有看到一个简单的解决方案。幸运的是,定义一个新的匹配器确实是一件容易的事。看看:
private class HasItemMatcher<T> extends BaseMatcher<List<T>> {
private final Matcher<Iterable<? super T>> iterableMatcher;
public HasItemMatcher(T value) {
this.iterableMatcher = CoreMatchers.hasItem(value);
}
@Override
public boolean matches(Object item) {
return iterableMatcher.matches(item);
}
@Override
public void describeTo(Description description) {
iterableMatcher.describeTo(description);
}
}
这段代码是不言自明的。它将所有工作委托给现有的匹配器。
考虑到这一点,您可以将测试重写为:
@Test
public void sampleTest() {
List<List<String>> testedList = new ArrayList<>();
List<String> firstList = new ArrayList<>();
firstList.add("1");
firstList.add("2");
List<String> secondList = new ArrayList<>();
secondList.add("2");
secondList.add("3");
testedList.add(firstList);
testedList.add(secondList);
Assert.assertThat(testedList, CoreMatchers.everyItem(new HasItemMatcher<>("2")));
}