Использование метода assertAll против утверждения в отдельных операторах
Метод assertAll используется для проверки всех переданных ему утверждений.
Вот что о методе говорится в официальной документации:
Утверждает, что все предоставленные
executables
не вызывают исключений.
Если какой-либо предоставленный
Executable
выдает исключение (т. е.Throwable
или любой его подкласс), все оставшиесяexecutables
все равно будут выполняться, а все исключения будут агрегированы и зарегистрированы вMultipleFailuresError
. Однако, еслиexecutable
генерирует исключение из черного списка — например,OutOfMemoryError
— выполнение немедленно останавливается, а исключение из черного списка создается как есть, но замаскировано как непроверенное исключение.
Предоставленный
heading
будет включен в строку сообщения дляMultipleFailuresError
.
Применение
@Test void testAssertions() { assertAll( () -> assertEquals("1", "1"), () -> assertTrue(1 == 2), ...... ); }
Использование assertAll против утверждения отдельно
Разница между передачей утверждений этому методу и утверждением их в отдельных утверждениях заключается в том, что «метод assertAllвыполняет все переданные ему утверждения, даже если какое-то утверждение не выполняется».
// Example of assertAll @Test void testAssertions() { assertAll( () -> assertEquals("1", "1"), () -> assertEquals("1", "2"), () -> assertTrue(1 == 2) ); } /* Output: org.opentest4j.MultipleFailuresError: Multiple Failures (2 failures) org.opentest4j.AssertionFailedError: expected: <1> but was: <2> org.opentest4j.AssertionFailedError: expected: <true> but was: <false> */
Если мы запишем утверждения в отдельные операторы, то выполнение теста будет немедленно заканчиваться всякий раз, когда утверждение терпит неудачу. Утверждения, следующие за ошибочным утверждением, не будут выполняться.
// Example of asserting separately @Test void testAssertions() { assertEquals("1", "1"); /* when the test fails here it throws an AssertionFailedError and the test fails. The below assertTrue will not be executed */ assertEquals("1", "2"); assertTrue(1 == 2); } /* Output: org.opentest4j.AssertionFailedError: Expected :1 Actual :2 */
Таким образом, выполнение всех утверждений даже в случае сбоя утверждения является преимуществом метода assertAll.
Работающий
Давайте проверим код метода assertAll, чтобы увидеть, как он работает.
// code from JUnit 5 static void assertAll(String heading, Stream<Executable> executables) { Preconditions.notNull(executables, "executables stream must not be null"); List<Throwable> failures = executables // .peek(executable -> Preconditions.notNull(executable, "individual executables must not be null"))// .map(executable -> { try { executable.execute(); return null; } catch (Throwable t) { BlacklistedExceptions.rethrowIfBlacklisted(t); return t; } }) // .filter(Objects::nonNull) // .collect(Collectors.toList()); if (!failures.isEmpty()) { MultipleFailuresError multipleFailuresError = new MultipleFailuresError(heading, failures); failures.forEach(multipleFailuresError::addSuppressed); throw multipleFailuresError; } }
Каждый объект/утверждение Executable выполняется в рамках try-catch, чтобы убедиться, что ошибка утверждения не вызывается сразу. Функция сопоставления/преобразования возвращает значение null, если тест проходит успешно,ивозвращает значение throwable, если тест не пройден.
Поток Executable’s преобразуется в поток Throwable’s. Ненулевые объекты фильтруются (неудачные утверждения) и собираются в список. Список оборачивается в MultipleFailuresError и выбрасывается в конце коллективно.
Это все на данный момент. Не стесняйтесь задавать любые вопросы или делиться любыми комментариями, которые у вас есть по поводу статьи. Увидимся в следующей статье.
Удачного кодирования!