[英]How do I assert an Iterable contains elements with a certain property?
[英]How do you assert that a `Collection` of `Collection`s contains elements containing certain elements?
假设我有String
的"foo"
, "bar"
和baz
并且给了我Stream<String[]> candidates
。
我现在要assertThat
, candidates
中的所有元素都是包含{"foo", "bar"}
(以任何顺序)或{"bar", "baz"}
(以任何顺序)的元组。
我最好怎么做?
第一步是使用Stream#allMatch(Predicate)
检查元组中[foo, bar]
或 [bar, baz]
以及元组的大小。
在第二步中,我将内部数组转换为Set<String>
,这可以轻松解决[foo, foo]
类的情况[foo, foo]
因为重复项将被删除,我们也可以将Set.contains()
用作O(1) )查找以检查元组流中是否存在[foo, bar]
或 [bar, baz]
:
class TupleTest {
@org.junit.jupiter.api.Test
void testTupleOfCandidates_True() {
Stream<String[]> candidates = Stream.of(new String[]{"bar", "foo"}, new String[]{"bar", "baz"});
assertTrue(isCandidateStreamValid(candidates));
candidates = Stream.of(new String[]{"bar", "foo"}, new String[]{"bar", "baz"});
assertTrue(isCandidateStreamValid(candidates));
}
@org.junit.jupiter.api.Test
void testTupleOfCandidates_False() {
Stream<String[]> candidates = Stream.of(new String[]{"foo", "foo"}, new String[]{"bar", "baz"});
assertFalse(isCandidateStreamValid(candidates));
candidates = Stream.of(new String[]{"bar", "foo"}, new String[]{"bar", "baz"}, new String[]{"baz", "bar"});
assertTrue(isCandidateStreamValid(candidates));
}
public boolean isCandidateStreamValid(Stream<String[]> candidates){
return candidates.allMatch(arr -> {
Set<String> data = new HashSet(Arrays.asList(arr));
return data.size() == 2
&&
((data.contains("foo") && data.contains("bar"))
||
(data.contains("bar") && data.contains("baz")));
});
}
}
为了简单起见,我将创建一个可以验证元组的函数。 此函数将在流中的每个元素上调用。 我还将创建第二个函数,该函数可以检查一个数组是否包含另一个数组的每个元素。 像这样:
import org.junit.Test;
import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
public class MyTest {
@Test
public void test(){
Stream<String[]> stream = Stream.of(new String[]{"foo", "bar"}, new String[]{"bar", "baz"});
stream.forEach(arr -> assertThat(validTuple(arr)).isTrue());
//Order does not matter:
stream = Stream.of(new String[]{"bar", "foo"}, new String[]{"baz", "bar"});
stream.forEach(arr -> assertThat(validTuple(arr)).isTrue());
//Invalid tuples
stream = Stream.of(new String[]{"foo", "asdf"}, new String[]{"foo", "baz"});
stream.forEach(arr -> assertThat(validTuple(arr)).isFalse());
}
private boolean validTuple(String[] array){
if(array.length != 2) return false;
return containsAll(array, "foo", "bar") || containsAll(array, "bar", "baz");
}
private boolean containsAll(String[] array, String... values){
for (String value : values) {
boolean containsValue = false;
for (String s : array) {
if(s.equals(value)){
containsValue = true;
break;
}
}
if(!containsValue){
return false;
}
}
return true;
}
}
现在,您可以轻松地将这些方法提取到专用类中,以便在需要时可以在其他测试中重用它们。
您可以使用allMatch
或allSatisfy
东西
assertThat(candidates).allMatch(candidate -> candidate.contains...)
要么
assertThat(candidates).allSatisfy(
candidate -> assertThat(candidate).satisfiesAnyOf(
c -> {
c.contains("foo");
c.contains("bar");
},
c -> {
c.contains("bar");
c.contains("baz");
})
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.