简体   繁体   English

您如何断定Collection的Collection包含包含某些元素的元素?

[英]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). 我现在要assertThatcandidates中的所有元素都是包含{"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 您可以使用allMatchallSatisfy东西

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.

相关问题 如何断言 Iterable 包含具有特定属性的元素? - How do I assert an Iterable contains elements with a certain property? 对集合的所有元素断言相同的条件 - Assert same condition on all elements of a collection 元素如何存储在集合中? - How elements are stored in a collection? 如何检查一个Collection在google-truth中至少包含N个匹配元素? - How do I check that a Collection contains at least N matching elements in google-truth? 有没有办法检查 Stream 是否包含所有集合元素? - Is there a way to check if a Stream contains all collection elements? 如何断言集合中的所有元素都具有它们之间相等的属性? - How to assert that all elements in the collection have a property which is equal among them? 如何安全地过滤集合中的元素? - How to safely filter elements in collection? 如何按属性查找集合中的元素? - How to find elements in a collection by property? 如何在Java集合元素的属性的子集上构建Morphia查询? - How to build a Morphia query on a subset of the properties of a Java Collection's elements? 如何使用一个额外的队列,没有其他集合,可能还有JAVA中的某些变量来反转队列中元素的顺序? - How do you reverse the order of the elements in a queue using one additional queue,no other collection, possibly some variables in JAVA?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM