#java #unit-testing #junit #assert
#java #модульное тестирование #junit #утверждать
Вопрос:
Я тестирую метод, чтобы увидеть, возвращает ли он правильную строку. Эта строка состоит из множества строк, порядок которых может меняться, таким образом, обычно получается 2 возможные комбинации. Этот порядок не важен для моего приложения.
Однако, поскольку порядок строк может измениться, написание просто инструкции Assert не сработает, поскольку иногда она пройдет тест, а иногда и не пройдет тест.
Итак, возможно ли написать тест, который будет утверждать фактическое строковое значение относительно 2 или более ожидаемых строковых значений и посмотреть, равно ли оно какому-либо из них?
Ответ №1:
Используя Hamcrest CoreMatcher
(входит в JUnit 4.4 и более поздние версии) и assertThat()
:
assertThat(myString, anyOf(is("value1"), is("value2")));
Комментарии:
1. В конечном итоге мне удалось это исправить, но по какой-то причине для меня JUnit 4 не имеет метода ‘assertThat’ в CoreMatcher. В итоге я объединил основную библиотеку Hamcrest с библиотекой JUnit, чтобы заставить ее работать.
2. Не для меня… Я просто вижу assertTrue
3. @Andrey: ты уверен, что проверил
org.junit.Assert
и неjunit.framework.Assert
проверял? Более поздние существуют только для обратной совместимости с JUnit 3 и не поддерживаютassertThat. In
org.junit. ` Assert’ был введен в JUnit 4.4. Поэтому, если у вас более ранняя версия, он будет отсутствовать.4. Вы пропустили одно ‘)’ в конце
assertThat
инструкции.5. @JiaHaoXu: действительно, теперь исправлено. Обратите внимание, что вы можете самостоятельно отредактировать (или предложить отредактировать) ответ на подобные опечатки.
Ответ №2:
Я бы использовал AssertJ для этого:
import static org.assertj.core.api.Assertions.*;
assertThat("hello").isIn("hello", "world");
Это более лаконично, и при сбое утверждения выдается описательное сообщение.
Ответ №3:
Я использую следующее, надеюсь, это поможет:
String expectedTitles[] = {"Expected1","Expected2"};
List<String> expectedTitlesList = Arrays.asList(expectedTitles);
assertTrue(expectedTitlesList.contains((actualTitle)));
Комментарии:
1.для тех, кто использует junit Assert
String expectedTitles[] = {"In-Progress","Completed"};
List<String> expectedTitlesList = Arrays.asList(expectedTitles);
Assert.assertTrue(expectedTitlesList.contains((transferRequest.getRequestStatus())));
2. Для тех, кто вынужден использовать junit 3, это хорошее решение.
Ответ №4:
Для этого вы можете использовать Hamcrest:
assertThat(testString, anyOf(
containsString("My first string"),
containsString("My other string")));
(Я вижу, что Иоахим только что ответил очень похоже ( 1)… я добавлю это в качестве другого примера.)
Комментарии:
1. Пожалуйста, добавьте соответствующие инструкции импорта к примеру, чтобы сделать его более понятным.
Ответ №5:
Я прочитал все ответы, но тот, который кажется мне наиболее компактным и выразительным, использует Hamcrest isOneOf
, который уже включен в 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)
[...]
Комментарии:
1. Какой оператор импорта у вас есть для isOneOf? Какая версия JUnit?
2. JUnit 4 с использованием Hamcrest 1.3 — hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest / …
3. Не рекомендуется: вместо этого используйте is(oneOf(…)).
Ответ №6:
Если вы используете junit, я бы просто сделал что-то вроде следующего:
assertTrue(myString.equals("Value1") || myString.equals("Value"));
Комментарии:
1. Это плохая практика в тестировании. Хотя логически это пройдет и завершится сбоем, когда это предполагается, проблема в том, что в случае сбоя у вас не будет описательного сообщения об ошибке. вместо этого вы получите что-то вроде «ожидаемое значение true, но оказалось false», что ничего не говорит вам о проблеме. Но при использовании сопоставителей hamcrest или assertj при сбое вы получите что-то вроде этого: ожидалось одно из следующих значений: «Value1», «Value2», но было «XYZ»
Ответ №7:
Рассмотрите возможность написания пользовательского сопоставления hamcrest, возвращаемого методом, в данном случае containsOneOf
, т.Е.:
assertThat(myString, containsOneOf("value1", "value2"));
В соответствии с «шаблонами xUnit» вам следует избегать условной логики в вашем сопоставителе, цикла с оператором break должно быть достаточно.
Взгляните на шаблоны Hamcrest и xUnit для получения дополнительной информации.
Ответ №8:
Если содержимое строки фиксировано, вы можете разделить его на окончания строк перед сравнением. Затем просто сравните каждую строку с набором ожидаемых значений. Что-то вроде этого:
Set<String> expectedValues = ...
String[] split = text.split("n");
for(String str : split) {
assert(expectedValues.contains(str));
}
Если вы хотите проверить, присутствуют ли все ожидаемые значения, вы можете утверждать это expectedValue.remove(str) == true
и утверждать после цикла, что набор пуст. Если некоторые строки могут встречаться несколько раз, вам придется использовать пакет вместо набора.
Ответ №9:
Самым простым / наиболее эффективным может быть
assert str.equals(result1) || str.equals(result2);
Это фактически не будет иметь накладных расходов, если у вас не включены утверждения.
Комментарии:
1. но в Android Studio я обнаружил, что утверждения не оцениваются в моих инструментальных тестах. Вместо этого мне нужно использовать assertTrue
2. @likejiujitsu вам нужно убедиться, что ea является опцией командной строки. assertEquals лучше всего подходит для тестирования, но используйте assert только в рабочей среде, поэтому его можно отключить.
3.
assert.assertequals(expected, actual)
не позволяет||
operator4. @Sanchit assetTrue делает.
5. Но при сбое это не покажет вам никакого значимого сообщения об ошибке. Использование hamcrest или assertj предоставляет вам что-то вроде «ожидаемые значения X, Y, но был Z»
Ответ №10:
Предполагая, что тестируемый метод возвращает массив, вы могли бы протестировать, используя arrayContainingInAnyOrder от Hamcrest . arrayContainingInAnyOrder от Hamcrest-а.
assertThat(result, is(arrayContainingInAnyOrder("value1", "value2", "value")))
Примечание: использование is
wrapper является чисто необязательным, используется только для улучшения читаемости.
Ответ №11:
Я думаю, вы можете просто использовать assertTrue:
assertTrue(testString.matches("string1|string2"));
Ответ №12:
Простое решение с использованием assertTrue.
Просто создайте List.of() ожидаемые значения и проверьте, содержит ли он ожидаемое значение.
assertTrue(List.of("expected_1", "expected_2").contains("actual))
Ответ №13:
Если у вас нет или вы не можете использовать сторонние библиотеки, кроме junit core, вы можете использовать этот небольшой вспомогательный метод:
public static void assertListContains(List<Object> expected, Object actual) {
if (!expected.contains(actual)) {
fail("Expected: " expected " Actual: " actual);
}
}
Преимущество, в отличие от других обходных ответов, заключается в том, что вы можете видеть, что ожидалось и что было фактическим:
org.opentest4j.AssertionFailedError: Expected: [1, 2] Actual: 3
Ответ №14:
Это старый пост, но я хотел получить простой ответ, не требующий добавления дополнительных библиотек. 🙂
Итак, я сделал :
String e
e = "ear"
j = "jars"
assert (j == "jar" || e == "ear")
или, если вы хотите, чтобы они оба были истинными
assert (j == "jar" amp;amp; e == "ear")
Ответ №15:
Мне кажется, это самое простое решение…
assert obtainedValue in [acceptedValue1, acceptedValue2]