Как утверждать фактическое значение против 2 или более ожидаемых значений? - PullRequest
22 голосов
/ 17 мая 2011

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

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

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

Ответы [ 13 ]

41 голосов
/ 17 мая 2011

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

assertThat(myString, anyOf(is("value1"), is("value2"));
17 голосов
/ 05 июля 2013

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

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

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

6 голосов
/ 17 мая 2011

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

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

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

3 голосов
/ 05 апреля 2016

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

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

assertTrue(expectedTitlesList.contains((actualTitle)));
2 голосов
/ 02 августа 2017

Я читаю все ответы, но тот, который кажется мне наиболее компактным и выразительным, использует 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 голосов
/ 17 мая 2011

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

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

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

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

1 голос
/ 17 мая 2011

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

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

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

1 голос
/ 17 мая 2011

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

assertTrue(myString.equals("Value1") || myString.equals("Value"));
1 голос
/ 17 мая 2011

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

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

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

0 голосов
/ 07 августа 2018

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

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

...