java JUnit检查异常抛出的消息是“stringA”还是“stringB”

5uzkadbs  于 2023-01-29  发布在  Java
关注(0)|答案(1)|浏览(106)

在我的代码中,我有一些像这样的模式(我试图尽可能简化):

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import java.util.Set;

public void funcSubSet() {
   final Set<String> setA = new HashSet<>(Arrays.asList("a", "b", "c", "d"));
   final Set<String> setB = new HashSet<>(Arrays.asList("a"));
   Preconditions.checkArgument(setB.constainsAll(setA),
                               "The strings %s are present in setA but not in setB",
                               Joiner.on(", ").join(setA.stream()
                                                   .filter(Predicate.not(setB::contains))
                                                   .iterator())
                               );
}

基本上,它检查setA是否完全包含在setB中。如果没有,抛出一个异常,并打印setA中的元素和setB中的元素(用逗号和空格分隔)。当我测试它时,问题是它有时会以不同的顺序输出setB中不包含的字符串,下面的测试用例偶尔会失败。

assertThrows(IllegalArgumentException.class,
             () -> funcSubSet()),
             "The strings b, c, d are present in setA but not in setB")

有时候输出结果是这样的:字符串d、B、c出现在集合A中,但不出现在集合B中。
我怎样才能使它不知道顺序呢?我怎样才能告诉hasMessage()或任何其他Assert我接受多个字符串呢?我检查了一下,什么也没找到。
我使用JUnit 5!

baubqpgj

baubqpgj1#

如果你能提供测试中从外部检查的集合(我推荐这样做是为了获得好的代码设计和高的可测试性),你可以提供一个java.util.LinkedHashSet<E>而不是HashSet来进行测试,这个类确保迭代顺序是第一次插入的顺序,所以你可以得到一个可预测的结果。
如果您不能为测试选择实际的Set实现,我将编写一个稍有不同的测试:

import org.junit.jupiter.api.Assertions;

//...

// expect permutation of:
//The strings b, c, d are present in setA but not in setB

Exception thrownException = Assertions.assertThrows(Exception.class, () -> funcSubSet());

String message = thrownException.getMessage();

Assertions.assertEquals("The strings ", message.substring(0, 12), "message start");
Assertions.assertEquals(" are present in setA but not in setB", message.substring(19), "message end");
String variables = message.substring(11,19);
Assertions.assertTrue(variables.contains(" b"), "contains b");
Assertions.assertTrue(variables.contains(" c"), "contains c");
Assertions.assertTrue(variables.contains(" d"), "contains d");

对于Assertions.assertThrows,您还可以期待一个固定的String,并使用捕获的异常来获得更多细节。org.junit.jupiter.api.Assertions是JUnit的一部分,不需要像AssertJ这样的第三方依赖项。

相关问题