[英]How do you assert that a `Collection` of `Collection`s contains elements containing certain elements?
Let's say I have String
s "foo"
, "bar"
and baz
假设我有String
的"foo"
, "bar"
和baz
and that I'm given a Stream<String[]> candidates
. 并且给了我Stream<String[]> candidates
。
I now want to assertThat
all elements in candidates
are tuples containing either {"foo", "bar"}
(in any order) or {"bar", "baz"}
(in any order). 我现在要assertThat
, candidates
中的所有元素都是包含{"foo", "bar"}
(以任何顺序)或{"bar", "baz"}
(以任何顺序)的元组。
How do I best do that? 我最好怎么做?
The first step is to use Stream#allMatch(Predicate)
to check the tuple for either the combination of [foo, bar]
or [bar, baz]
and the size of the tuple. 第一步是使用Stream#allMatch(Predicate)
检查元组中[foo, bar]
或 [bar, baz]
以及元组的大小。
In the second step I have converted the inner array into a Set<String>
which makes it easy to resolve cases like [foo, foo]
as the duplicates would be removed and also we can use Set.contains()
for a O(1) lookup to check either [foo, bar]
or [bar, baz]
is present in the stream of tuples: 在第二步中,我将内部数组转换为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")));
});
}
}
For simplicity, I'd create a function that can validate a tuple. 为了简单起见,我将创建一个可以验证元组的函数。 This function will be called on each element in the stream. 此函数将在流中的每个元素上调用。 I would also create a second function that can check whether an array contains each element of another array. 我还将创建第二个函数,该函数可以检查一个数组是否包含另一个数组的每个元素。 Something like this: 像这样:
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;
}
}
You can now easily extract those methods to a dedicated class so you can re-use them in other tests if need be. 现在,您可以轻松地将这些方法提取到专用类中,以便在需要时可以在其他测试中重用它们。
You can use allMatch
or allSatisfy
something like 您可以使用allMatch
或allSatisfy
东西
assertThat(candidates).allMatch(candidate -> candidate.contains...)
or 要么
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.