如何根据2个或更多预期值断言实际值?

时间:2011-05-17 09:20:33

标签: java unit-testing junit assert

我正在测试一个方法,看它是否返回正确的字符串。该字符串由许多行组成,其顺序可能会发生变化,因此通常会提供2种可能的组合。该命令对我的申请并不重要。

但是,因为行的顺序可能会改变,所以只写一个Assert语句是行不通的,因为有时它会通过测试,有时它会使测试失败。

那么,是否可以编写一个测试,该测试将针对2个或更多预期字符串值断言实际字符串值,并查看它是否等于其中任何一个?

14 个答案:

答案 0 :(得分:39)

使用Hamcrest CoreMatcher(包含在JUnit 4.4及更高版本中)和assertThat()

assertThat(myString, anyOf(is("value1"), is("value2"));

答案 1 :(得分:17)

我会使用AssertJ

assertThat("hello").isIn("hello", "world");

它更简洁,当断言失败时它会给你一条描述性的信息。

答案 2 :(得分:6)

您可以使用Hamcrest

assertThat(testString, anyOf(
    containsString("My first string"), 
    containsString("My other string")));

(我看到约阿希姆的答案非常相似(+1)......我会将此作为另一个例子添加。)

答案 3 :(得分:3)

我正在使用以下内容,我希望这会有所帮助:

String expectedTitles[] = {"Expected1","Expected2"};
List<String> expectedTitlesList = Arrays.asList(expectedTitles);

assertTrue(expectedTitlesList.contains((actualTitle)));

答案 4 :(得分:2)

考虑编写一个方法返回的自定义hamcrest匹配器,在本例中为containsOneOf,即:

assertThat(myString, containsOneOf("value1", "value2"));

为了与“xUnit模式”保持一致,你应该避免匹配器中的条件逻辑,带有break语句的循环就足够了。

有关详细信息,请查看HamcrestxUnit Patterns

答案 5 :(得分:2)

我阅读了所有答案,但对我来说最紧凑和最具表现力的是使用已经包含在JUnit中的Hamcrest isOneOf

assertThat(result, isOneOf("value1", "value2"));

在失败时给你一个很好的错误信息。

java.lang.AssertionError: 
Expected: one of {"value1", "value2"}
     but: was "value"
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
[...]

答案 6 :(得分:1)

如果某行的内容是固定的,您可以在比较之前将其拆分为行尾。然后简单地将每一行与一组期望值进行比较。 像这样:

   Set<String> expectedValues = ...
   String[] split = text.split("\n");
   for(String str : split) {
      assert(expectedValues.contains(str));
   }

如果要检查是否存在所有预期值,可以断言expectedValue.remove(str) == true并在循环后断言Set为空。如果某些行可能多次出现,则必须使用Bag而不是Set。

答案 7 :(得分:1)

如果您使用junit,我会执行以下操作:

assertTrue(myString.equals("Value1") || myString.equals("Value"));

答案 8 :(得分:1)

最简单/最有效的可能是

assert str.equals(result1) || str.equals(result2);

如果没有打开断言,这将实际上没有开销。

答案 9 :(得分:0)

假设测试中的方法返回一个数组,您可以使用Hamcrest arrayContainingInAnyOrder进行测试。

assertThat(result, is(arrayContainingInAnyOrder("value1", "value2", "value")))

注意:使用is包装器纯粹是可选的,仅用作可读性糖。

答案 10 :(得分:0)

这是一篇过时的文章,但是我想有一个本机简单的答案,而无需添加额外的库。 :)

所以我做到了:

String e
e = "ear"
j = "jars"

assert (j == "jar" || e == "ear")

或者如果您希望它们都为真

assert (j == "jar" && e == "ear")

答案 11 :(得分:0)

我认为您可以只使用assertTrue:

assertTrue(testString.matches("string1|string2"));

答案 12 :(得分:0)

在我看来,这是最简单的解决方案...

assert obtainedValue in [acceptedValue1, acceptedValue2]

答案 13 :(得分:-1)

我正在使用以下内容:

assert expected1.equals(actual) || expected2.equals(actual);