it-roy-ru.com

Как утверждать фактическое значение против 2 или более ожидаемых значений?

Я тестирую метод, чтобы увидеть, возвращает ли он правильную строку. Эта строка состоит из множества строк, порядок которых может измениться, что обычно дает 2 возможных комбинации. Этот порядок не важен для моего заявления.

Однако, поскольку порядок строк может измениться, написание только оператора Assert не сработает, поскольку иногда оно проходит тест, а иногда не проходит тест.

Итак, возможно ли написать тест, который будет утверждать фактическое строковое значение против 2 или более ожидаемых строковых значений и посмотреть, равно ли оно любому из них?

21
Andrei

Использование Hamcrest CoreMatcher (входит в JUnit 4.4 и более поздние версии) и assertThat():

assertThat(myString, anyOf(is("value1"), is("value2"));
39
Joachim Sauer

Я бы использовал AssertJ для этого:

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

Это более кратко и даст вам описательное сообщение, когда утверждение не удастся.

17
Jonathan

Вы можете использовать Hamcrest для этого:

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

(Я вижу, что Иоахим только что ответил очень похоже (+1) ... я добавлю это в качестве другого примера.)

6
alpian

Подумайте о том, чтобы написать пользовательское сопоставление подколенного сухожилия, возвращаемое методом, в данном случае containsOneOf, т.е.

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

В соответствии с «шаблонами xUnit» вы должны избегать условной логики в вашем сопоставителе, цикл с оператором break должен быть достаточным.

Взгляните на Hamcrest и xUnit Patterns для получения дополнительной информации.

2
murungu

Я читаю все ответы, но тот, который кажется мне наиболее компактным и выразительным, использует isOneOf Hamcrest, который уже включен в JUnit

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

который дает вам хорошее сообщение об ошибке при сбое.

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

Я использую следующее, я надеюсь, что это поможет: 

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

assertTrue(expectedTitlesList.contains((actualTitle)));
1
Barun Kumar

Самый простой/самый эффективный может быть

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

Это фактически не будет иметь накладных расходов, когда у вас нет включенных утверждений.

1
Peter Lawrey

Если содержимое строки является фиксированным, вы можете разбить его в конце строки перед сравнением. Затем просто сравните каждую строку с набором ожидаемых значений . Примерно так:

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

Если вы хотите проверить наличие всех ожидаемых значений, вы можете утверждать, что expectedValue.remove(str) == true, и после цикла утверждать, что набор пуст. Если некоторые строки могут встречаться несколько раз, вы должны использовать Bag вместо Set.

1
joe776

Если вы используете junit, я бы просто сделал что-то вроде следующего:

assertTrue(myString.equals("Value1") || myString.equals("Value"));
1
Tom Jefferys

Я думаю, что вы можете просто использовать assertTrue:

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

0
OSrookie

Предполагая, что тестируемый метод возвращает массив, вы можете протестировать, используя Hamcrest's arrayContainedInAnyOrder .

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

Примечание: использование оболочки is является необязательным, используется только как удобочитаемость.

0
Chris Willmore

Это старый пост, но я хотел получить простой ответ без добавления дополнительных библиотек. :)

Так я и сделал : 

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

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

или если вы хотите, чтобы они оба были правдой

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