Java 如何断言集合中的集合包含包含特定元素的元素?
假设我有Java 如何断言集合中的集合包含包含特定元素的元素?,java,unit-testing,junit,hamcrest,assertj,Java,Unit Testing,Junit,Hamcrest,Assertj,假设我有Strings“foo”,“bar”和baz 我得到了一个候选流 现在我想断言候选中的所有元素都是元组,包含{“foo”,“bar”}(以任何顺序)或{“bar”,“baz”}(以任何顺序) 如何最好地做到这一点?第一步是使用Stream#allMatch(谓词)检查元组中[foo,bar]或[bar,baz]的组合以及元组的大小 在第二步中,我将内部数组转换为一个集合,这样就可以很容易地解决类似[foo,foo]的情况,因为重复项将被删除,而且我们还可以使用Set.contains()
String
s“foo”
,“bar”
和baz
我得到了一个候选流
现在我想断言候选中的所有元素都是元组,包含{“foo”,“bar”}
(以任何顺序)或{“bar”,“baz”}
(以任何顺序)
如何最好地做到这一点?第一步是使用Stream#allMatch(谓词)
检查元组中[foo,bar]
或[bar,baz]
的组合以及元组的大小
在第二步中,我将内部数组转换为一个集合
,这样就可以很容易地解决类似[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")));
});
}
}
class-TupleTest{
@org.junit.jupiter.api.Test
void testTupleOfCandidates_True(){
候选流=Stream.of(新字符串[]{“bar”,“foo”},新字符串[]{“bar”,“baz”});
assertTrue(isCandidateStreamValid(候选者));
候选项=Stream.of(新字符串[]{“bar”,“foo”},新字符串[]{“bar”,“baz”});
assertTrue(isCandidateStreamValid(候选者));
}
@org.junit.jupiter.api.Test
void testTupleOfCandidates_False(){
候选流=Stream.of(新字符串[]{“foo”,“foo”},新字符串[]{“bar”,“baz”});
assertFalse(isCandidateStreamValid(候选者));
候选项=Stream.of(新字符串[]{“bar”,“foo”},新字符串[]{“bar”,“baz”},新字符串[]{“baz”,“bar”});
assertTrue(isCandidateStreamValid(候选者));
}
公共布尔值isCandidateStreamValid(流候选){
返回候选者。所有匹配(arr->{
Set data=newhashset(Arrays.asList(arr));
返回数据。大小()==2
&&
((data.contains(“foo”)和&data.contains(“bar”))
||
(数据包含(“baz”)&数据包含(“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;
}
}
import org.junit.Test;
导入java.util.stream.stream;
导入静态org.assertj.core.api.Assertions.assertThat;
公共类MyTest{
@试验
公开无效测试(){
Stream-Stream=Stream.of(新字符串[]{“foo”,“bar”},新字符串[]{“bar”,“baz”});
stream.forEach(arr->assertThat(validTuple(arr)).isTrue();
//顺序无关紧要:
stream=stream.of(新字符串[]{“bar”,“foo”},新字符串[]{“baz”,“bar”});
stream.forEach(arr->assertThat(validTuple(arr)).isTrue();
//无效元组
stream=stream.of(新字符串[]{“foo”,“asdf”},新字符串[]{“foo”,“baz”});
stream.forEach(arr->assertThat(validTuple(arr)).isFalse();
}
私有布尔有效整数(字符串[]数组){
如果(array.length!=2)返回false;
返回containsAll(数组,“foo”,“bar”)| containsAll(数组,“bar”,“baz”);
}
私有布尔containsAll(字符串[]数组,字符串…值){
for(字符串值:值){
布尔值containsValue=false;
for(字符串s:数组){
如果(s.等于(值)){
containsValue=true;
打破
}
}
如果(!containsValue){
返回false;
}
}
返回true;
}
}
现在,您可以轻松地将这些方法提取到一个专用类中,以便在需要时在其他测试中重复使用它们。您可以使用allMatch
或allsummit
之类的方法
assertThat(candidates).allMatch(candidate -> candidate.contains...)
或
比如说,{“foo”,“foo”}
,这将失败。(您还忘了检查arr
的大小是否为2,顺便说一句。)@User1291感谢您捕捉到了这一点,我修复了我之前发布的代码,它应该适用于所有情况。如果我们继续这样做,我建议将您的函数设置为谓词
,并使用stream.allMatch(validTuple)
。
assertThat(candidates).allSatisfy(
candidate -> assertThat(candidate).satisfiesAnyOf(
c -> {
c.contains("foo");
c.contains("bar");
},
c -> {
c.contains("bar");
c.contains("baz");
})
);