Тест на ошибку java

Время на прочтение
3 мин

Количество просмотров 15K

Это продолжение туториала по JUnit 5. Введение опубликовано здесь.

В JUnit 5, чтобы написать тестовый код, который, как ожидается, вызовет исключение, мы должны использовать Assertions.assertThrows().

В данном примере ожидается, что тестовый код в комментированном блоке вызовет исключение типа ApplicationException.

Использование Assertions.assertThrows()

@Test
void testExpectedException() {

  ApplicationException thrown = Assertions.assertThrows(ApplicationException.class, () -> {
           //Code under test
  });

  Assertions.assertEquals("some message", exception.getMessage());
}

Оглавление

  1. Assertions API assertThrows ().

    • Синтаксис

    • Вывод теста

  2. Ожидаемое исключение генерируется в тесте.

  3. Сгенерировано исключение другого типа, или не сгенерировано исключение

1. Assertions API assertThrows ()

1.1. Синтаксис

Метод assertThrows() утверждает, что выполнение прилагаемого исполняемого блока или лямбда — выражения вызывает исключение типа expectedType. Это перегруженный метод, который принимает следующие параметры.

static <T extends Throwable>T assertThrows(Class<T> expectedType, Executable executable)

static <T extends Throwable>T assertThrows(Class<T> expectedType, Executable executable, String message)

static <T extends Throwable>T assertThrows(Class<T> expectedType, Executable executable, Supplier<String> messageSupplier)
  • expectedType — ожидается, что тестовый код вызовет исключение этого типа.

  • message — если исполняемый код не вызывает никаких исключений, это сообщение будет напечатано вместе с результатом FAIL.

  • messageSupplier — сообщение будет извлечено из него в случае неудачи теста.

1.2. Вывод теста

Если в блоке не было генерировано исключение, executable, то assertThrows() вернет FAIL.

Если выбрасывается исключение другого типа, assertThrows() будет FAIL.

Если блок кода вызывает исключение класса, который является подтипом исключения expectedType, только тогда assertThrows() вернет PASS.

Например, если мы ожидаем, IllegalArgumentException и тест выдает ошибку NumberFormatException, тогда и вывод теста будет PASSпотому что NumberFormatException расширяет класс IllegalArgumentException.

Кроме того, если мы передадим Exception.class в качестве ожидаемого типа исключения, любое исключение, выброшенное из исполняемого блока, сделает результат assertion равным PASS, поскольку Exception является супертипом для всех исключений.

2. Ожидаемое исключение генерируемое в тесте

Ниже приведен очень простой тест, который ожидает, что исключение NumberFormatException будет сгенерировано при выполнении предоставленного блока кода.

Оба теста выдают PASS

@Test
void testExpectedException() {

	NumberFormatException thrown = Assertions.assertThrows(NumberFormatException.class, () -> {
		Integer.parseInt("One");
	}, "NumberFormatException was expected");
	
	Assertions.assertEquals("For input string: "One"", thrown.getMessage());
}

@Test
void testExpectedExceptionWithParentType() {

	Assertions.assertThrows(IllegalArgumentException.class, () -> {
		Integer.parseInt("One");
	});
}
  • В тесте testExpectedException, исполняемый код Integer.parseInt("One") генерирует исключение NumberFormatException, если аргумент метода не является допустимым текстовым представлением числа. Метод assertThrows() ожидает это исключение, так что результат теста PASS.

  • В тесте testExpectedExceptionWithParentType, мы выполняем тот же код, но на этот раз мы принимаем исключение IllegalArgumentException, родительское для NumberFormatException. Этот тест тоже проходит.

3. Сгенерировано исключение другого типа, или не сгенерировано исключение

Если исполняемый код вызывает исключение любого другого типа, то результат теста будет FAIL.

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

Например, в приведенном ниже примере "1"это допустимое число, поэтому исключение не возникает. Этот тест завершится ошибкой с сообщением в консоли.

@Test
void testExpectedExceptionFail() {
 
	NumberFormatException thrown = Assertions
				.assertThrows(NumberFormatException.class, () -> {
					Integer.parseInt("1");
				}, "NumberFormatException error was expected");
	
	Assertions.assertEquals("Some expected message", thrown.getMessage());
}

В этом посте мы узнали, как написать тест, ожидающий возникновение исключений. Эти тесты полезны при тестировании кода, написанного в блоках catch.

Хорошего изучения!!!

Скачать исходный код

How do you verify that code throws exceptions as expected?
Verifying that code completes normally is important, but making sure the code behaves as expected in exceptional situations is vital too. For example:

new ArrayList<Object>().get(0);

This code should throw an IndexOutOfBoundsException. There are multiple ways in JUnit to write a test to verify this behavior.

Using assertThrows Method

The method assertThrows has been added to the Assert class in version 4.13. With this method you can assert that a given function call (specified, for instance, as a lambda expression or method reference) results in a particular type of exception being thrown. In addition it returns the exception that was thrown, so that further assertions can be made (e.g. to verify that the message and cause are correct). Furthermore, you can make assertions on the state of a domain object after the exception has been thrown:

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;
import org.junit.Test;

@Test
public void testExceptionAndState() {
  List<Object> list = new ArrayList<>();

  IndexOutOfBoundsException thrown = assertThrows(
      IndexOutOfBoundsException.class,
      () -> list.add(1, new Object()));

  // assertions on the thrown exception
  assertEquals("Index: 1, Size: 0", thrown.getMessage());
  // assertions on the state of a domain object after the exception has been thrown
  assertTrue(list.isEmpty());
}

Try/Catch Idiom

If you project is not yet using JUnit 4.13 or your code base does not support lambdas, you can use the try/catch idiom which prevailed in JUnit 3.x:

@Test
public void testExceptionMessage() {
  List<Object> list = new ArrayList<>();
    
  try {
    list.get(0);
    fail("Expected an IndexOutOfBoundsException to be thrown");
  } catch (IndexOutOfBoundsException anIndexOutOfBoundsException) {
    assertThat(anIndexOutOfBoundsException.getMessage(), is("Index: 0, Size: 0"));
  }
}

Be aware that fail() throws an AssertionError, so you cannot use the above idiom to verify that a method call should throw an AssertionError.

Specifying the expected annotation via the @Test annotation.

The @Test annotation has an optional parameter «expected» that takes as values subclasses of Throwable. If we wanted to verify that ArrayList throws the correct exception, we could write:

@Test(expected = IndexOutOfBoundsException.class) 
public void empty() { 
  new ArrayList<Object>().get(0); 
}

The expected parameter should be used with care. The above test will pass if any code in the method throws IndexOutOfBoundsException. Using the method you also cannot test the value of the message in the exception, or the state of a domain object after the exception has been thrown.

For these reasons, the previous approaches are recommended.

ExpectedException Rule

Another way to test exceptions is the ExpectedException rule, but that approach has been deprecated in JUnit 4.13. This rule let you indicate not only what exception you are expecting, but also the exception message you are expecting:

@Rule
public ExpectedException thrown = ExpectedException.none();

@Test
public void shouldTestExceptionMessage() throws IndexOutOfBoundsException {
  List<Object> list = new ArrayList<Object>();
 
  thrown.expect(IndexOutOfBoundsException.class);
  thrown.expectMessage("Index: 0, Size: 0");
  list.get(0); // execution will never get past this line
}

The expectMessage also lets you use Matchers, which gives you a bit more flexibility in your tests. An example:

thrown.expectMessage(CoreMatchers.containsString("Size: 0"));

Moreover, you can use Matchers to inspect the Exception, useful if it has embedded state you wish to verify. For example

import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.startsWith;

import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

public class TestExy {
  @Rule
  public ExpectedException thrown = ExpectedException.none();

  @Test
  public void shouldThrow() {
    TestThing testThing = new TestThing();
    thrown.expect(NotFoundException.class);
    thrown.expectMessage(startsWith("some Message"));
    thrown.expect(hasProperty("response", hasProperty("status", is(404))));
    testThing.chuck();
  }

  private class TestThing {
    public void chuck() {
      Response response = Response.status(Status.NOT_FOUND).entity("Resource not found").build();
      throw new NotFoundException("some Message", response);
    }
  }
}

For an expanded discussion of the ExpectedException rule, see this blog post.

Do note that when the test calls the method under test that throws the exception, no code in the test after the method will execute (because the method under test is throwing the exception). This can lead to confusion, which is one of the reasons why ExpectedException.none() is deprecated.

tl;dr

  • post-JDK8 : Use AssertJ or custom lambdas to assert exceptional behaviour.

  • pre-JDK8 : I will recommend the old good trycatch block. (Don’t forget to add a fail() assertion before the catch block)

Regardless of Junit 4 or JUnit 5.

the long story

It is possible to write yourself a do it yourself trycatch block or use the JUnit tools (@Test(expected = ...) or the @Rule ExpectedException JUnit rule feature).

But these ways are not so elegant and don’t mix well readability wise with other tools. Moreover, JUnit tooling does have some pitfalls.

  1. The trycatch block you have to write the block around the tested behavior and write the assertion in the catch block, that may be fine but many find that this style interrupts the reading flow of a test. Also, you need to write an Assert.fail at the end of the try block. Otherwise, the test may miss one side of the assertions; PMD, findbugs or Sonar will spot such issues.

  2. The @Test(expected = ...) feature is interesting as you can write less code and then writing this test is supposedly less prone to coding errors. But this approach is lacking in some areas.

    • If the test needs to check additional things on the exception like the cause or the message (good exception messages are really important, having a precise exception type may not be enough).
    • Also as the expectation is placed around in the method, depending on how the tested code is written then the wrong part of the test code can throw the exception, leading to false-positive test and I’m not sure that PMD, findbugs or Sonar will give hints on such code.

      @Test(expected = WantedException.class)
      public void call2_should_throw_a_WantedException__not_call1() {
          // init tested
          tested.call1(); // may throw a WantedException
      
          // call to be actually tested
          tested.call2(); // the call that is supposed to raise an exception
      }
      
  3. The ExpectedException rule is also an attempt to fix the previous caveats, but it feels a bit awkward to use as it uses an expectation style, EasyMock users know very well this style. It might be convenient for some, but if you follow Behaviour Driven Development (BDD) or Arrange Act Assert (AAA) principles the ExpectedException rule won’t fit in those writing style. Aside from that it may suffer from the same issue as the @Test way, depending on where you place the expectation.

    @Rule ExpectedException thrown = ExpectedException.none()
    
    @Test
    public void call2_should_throw_a_WantedException__not_call1() {
        // expectations
        thrown.expect(WantedException.class);
        thrown.expectMessage("boom");
    
        // init tested
        tested.call1(); // may throw a WantedException
    
        // call to be actually tested
        tested.call2(); // the call that is supposed to raise an exception
    }
    

    Even the expected exception is placed before the test statement, it breaks your reading flow if the tests follow BDD or AAA.

    Also, see this comment issue on JUnit of the author of ExpectedException. JUnit 4.13-beta-2 even deprecates this mechanism:

    Pull request #1519: Deprecate ExpectedException

    The method Assert.assertThrows provides a nicer way for verifying exceptions. In addition, the use of ExpectedException is error-prone when used with other rules like TestWatcher because the order of rules is important in that case.

So these above options have all their load of caveats, and clearly not immune to coder errors.

  1. There’s a project I became aware of after creating this answer that looks promising, it’s catch-exception.

    As the description of the project says, it let a coder write in a fluent line of code catching the exception and offer this exception for the latter assertion. And you can use any assertion library like Hamcrest or AssertJ.

    A rapid example taken from the home page :

    // given: an empty list
    List myList = new ArrayList();
    
    // when: we try to get the first element of the list
    when(myList).get(1);
    
    // then: we expect an IndexOutOfBoundsException
    then(caughtException())
            .isInstanceOf(IndexOutOfBoundsException.class)
            .hasMessage("Index: 1, Size: 0") 
            .hasNoCause();
    

    As you can see the code is really straightforward, you catch the exception on a specific line, the then API is an alias that will use AssertJ APIs (similar to using assertThat(ex).hasNoCause()...). At some point the project relied on FEST-Assert the ancestor of AssertJ. EDIT: It seems the project is brewing a Java 8 Lambdas support.

    Currently, this library has two shortcomings :

    • At the time of this writing, it is noteworthy to say this library is based on Mockito 1.x as it creates a mock of the tested object behind the scene. As Mockito is still not updated this library cannot work with final classes or final methods. And even if it was based on Mockito 2 in the current version, this would require to declare a global mock maker (inline-mock-maker), something that may not what you want, as this mock maker has different drawbacks that the regular mock maker.

    • It requires yet another test dependency.

    These issues won’t apply once the library supports lambdas. However, the functionality will be duplicated by the AssertJ toolset.

    Taking all into account if you don’t want to use the catch-exception tool, I will recommend the old good way of the trycatch block, at least up to the JDK7. And for JDK 8 users you might prefer to use AssertJ as it offers may more than just asserting exceptions.

  2. With the JDK8, lambdas enter the test scene, and they have proved to be an interesting way to assert exceptional behaviour. AssertJ has been updated to provide a nice fluent API to assert exceptional behaviour.

    And a sample test with AssertJ :

    @Test
    public void test_exception_approach_1() {
        ...
        assertThatExceptionOfType(IOException.class)
                .isThrownBy(() -> someBadIOOperation())
                .withMessage("boom!"); 
    }
    
    @Test
    public void test_exception_approach_2() {
        ...
        assertThatThrownBy(() -> someBadIOOperation())
                .isInstanceOf(Exception.class)
                .hasMessageContaining("boom");
    }
    
    @Test
    public void test_exception_approach_3() {
        ...
        // when
        Throwable thrown = catchThrowable(() -> someBadIOOperation());
    
        // then
        assertThat(thrown).isInstanceOf(Exception.class)
                          .hasMessageContaining("boom");
    }
    
  3. With a near-complete rewrite of JUnit 5, assertions have been improved a bit, they may prove interesting as an out of the box way to assert properly exception. But really the assertion API is still a bit poor, there’s nothing outside assertThrows.

    @Test
    @DisplayName("throws EmptyStackException when peeked")
    void throwsExceptionWhenPeeked() {
        Throwable t = assertThrows(EmptyStackException.class, () -> stack.peek());
    
        Assertions.assertEquals("...", t.getMessage());
    }
    

    As you noticed assertEquals is still returning void, and as such doesn’t allow chaining assertions like AssertJ.

    Also if you remember name clash with Matcher or Assert, be prepared to meet the same clash with Assertions.

I’d like to conclude that today (2017-03-03) AssertJ‘s ease of use, discoverable API, the rapid pace of development and as a de facto test dependency is the best solution with JDK8 regardless of the test framework (JUnit or not), prior JDKs should instead rely on trycatch blocks even if they feel clunky.

This answer has been copied from another question that don’t have the same visibility, I am the same author.

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

Ниже описаны пять способов, как в тестовом фреймворке JUnit перехватить ожидаемое исключение и проверить его свойства. Первые четыре из них можно использовать в JUnit 4, а последний способ использует новые возможности JUnit 5.

В качестве примера для демонстрации возьмём тест для функции стандартной библиотеки, создающей временный файл. Будем проверять, что при попытке создания файла в несуществующей директории возникает исключение типа IOException. При этом предварительно в том же самом тесте создаётся временная директория и тут же удаляется, так что мы получаем гарантированно несуществующую директорию, в которой и пытаемся создать файл:

import org.junit.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class MyTest {
  @Test
  public void testCreateTempFile() throws IOException {
    Path tmpDir = Files.createTempDirectory("tmp");
    tmpDir.toFile().delete();
    Path tmpFile = Files.createTempFile(tmpDir, "test", ".txt");
  }
}

Разумеется, в таком виде тест упадёт, а в отчёте будет написано, что возникло исключение. А нам нужно, чтобы тест в этом случае наоборот помечался как успешный. Посмотрим, как это можно исправить.

1. @Test

Самый простой способ сообщить тестовому фреймворку о том, что ожидается исключение – указать дополнительный параметр expected в аннотации @Test:

import org.junit.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class MyTest {
  @Test(expected = IOException.class)
  public void testCreateTempFile() throws IOException {
    Path tmpDir = Files.createTempDirectory("tmp");
    tmpDir.toFile().delete();
    Path tmpFile = Files.createTempFile(tmpDir, "test", ".txt");
  }
}

Этот параметр должен содержать тип ожидаемого исключения. Если возникнет исключение именно такого типа – тест пройдёт успешно. Если возникнет исключение другого типа или не возникнет вовсе – тест упадёт.

Достоинства:

  • Простота и краткость.

Недостатки:

  • Нельзя проверить текст сообщения или другие свойства возникшего исключения.
  • Нельзя понять, где именно возникло исключение. В рассматриваемом примере оно могло быть выброшено не тестируемой функцией, а чуть раньше, при попытке создать временную директорию. Тест даже не смог добраться до вызова тестируемой функции – но при этом в отчёте он помечается как успешно пройденный!

Вторая из упомянутых проблем настолько ужасна, что я никому никогда не рекомендую использовать этот способ.

2. try-catch

Оба недостатка можно устранить, если перехватывать исключение явно при помощи конструкции try-catch:

import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class MyTest {
  @Test
  public void testCreateTempFile() throws IOException {
    Path tmpDir = Files.createTempDirectory("tmp");
    tmpDir.toFile().delete();
    try {
      Path tmpFile = Files.createTempFile(tmpDir, "test", ".txt");
      Assert.fail("Expected IOException");
    } catch (IOException thrown) {
      Assert.assertNotEquals("", thrown.getMessage());
    }
    // дальше идёт какой-то другой код
    // в нём тоже может появиться неожиданный IOException
    // если это случится -- тест упадёт
  }
}

Если исключение возникает до блока try – тест падает, мы узнаём о том, что у него возникли проблемы.

Если тестируемая функция не выбрасывает вообще никакого исключения – мы попадаем на fail() в следующей строке, тест падает.

Если она выбрасывает исключение неподходящего типа – блок catch не ловит его, тест опять таки падает.

Успешно он завершается только тогда, когда тестируемая функция выбрасывает исключение нужного типа.

Тест стал более надёжным, он больше не пропускает баги. А в блоке catch можно проверить свойства пойманного исключения.

3. @Rule

Однако работать с конструкцией try-catch неудобно.

Чтобы избавиться от неё, можно воспользоваться правилом ExpectedException, входящим в стандартный дистрибутив JUnit 4:

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;

public class MyTest {
  @Rule
  public ExpectedException thrown = ExpectedException.none();

  @Test
  public void testCreateTempFile() throws IOException {
    Path tmpDir = Files.createTempDirectory("tmp");
    tmpDir.toFile().delete();
    thrown.expect(IOException.class);
    thrown.expectMessage(not(equalTo("")));
    Path tmpFile = Files.createTempFile(tmpDir, "test", ".txt");
    thrown = ExpectedException.none();
    // дальше идёт какой-то другой код
    // в нём тоже может появиться неожиданный IOException
    // если это случится -- тест упадёт
  }
}

Теперь код имеет простую плоскую структуру, хотя общее количество строк кода, к сожалению, увеличилось.

Но главная проблема этого способа заключается в том, что проверки в таком стиле выглядят противоестественно – сначала описывается поведение, а потом вызывается функция. Конечно, это дело вкуса, но мне нравится, когда проверки располагаются после вызова тестируемой функции.

4. AssertJ / catch-throwable

Более красивый способ, использующий возможности Java 8, предлагают дополнительные библиотеки, такие как AssertJ или catch-throwable. Вот пример работы с AssertJ:

import org.junit.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;

public class MyTest {
  @Test
  public void testCreateTempFile() throws IOException {
    Path tmpDir = Files.createTempDirectory("tmp");
    tmpDir.toFile().delete();
    Throwable thrown = catchThrowable(() -> {
      Files.createTempFile(tmpDir, "test", ".txt");
    });
    assertThat(thrown).isInstanceOf(IOException.class);
    assertThat(thrown.getMessage()).isNotBlank();
    // дальше идёт какой-то другой код
    // в нём тоже может появиться неожиданный IOException
    // если это случится -- тест упадёт
  }
}

Обращение к тестирумой функции оформлено в виде лямбда-выражения (анонимной функции), которое передаётся в “ловушку” для исключений catchThrowable. Она перехватывает возникающее исключение и возвращает его как результат своей работы, давая возможность сохранить его в переменную и затем проверить его свойства. При этом проверки находятся после вызова тестируемой функции, читать код легче.

А если исключение не возникнет – “ловушка” сама выбросит исключение и тест упадёт.

5. JUnit 5

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

Уже предоставляют. Перехват исключений в JUnit 5 выглядит очень похоже на предыдущий пример:

import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class MyTest {
  @Test
  public void testCreateTempFile() throws IOException {
    Path tmpDir = Files.createTempDirectory("tmp");
    tmpDir.toFile().delete();
    Throwable thrown = assertThrows(IOException.class, () -> {
      Files.createTempFile(tmpDir, "test", ".txt");
    });
    assertNotNull(thrown.getMessage());
    // дальше идёт какой-то другой код
    // в нём тоже может появиться неожиданный IOException
    // если это случится -- тест упадёт
  }
}

Раньше такая возможность в JUnit отсутствовала, потому что предыдущие версии JUnit были ориентированы на более старые версии Java, где не было лямбда-выражений и написать подобный код было просто невозможно. Да, можно сделать нечто подобное с помощью анонимных классов, но это выглядит настолько ужасно, что конструкция try-catch кажется верхом изящества.

Так что если вам приходится писать тесты, в которых проверяется возникновение исключений – есть повод присмотреться к новым возможностям JUnit 5.


Contents

Introduction

In this article, we look at how to test exceptions using JUnit5. We will cover how to verify an exception, verify a specific
exception thrown, No exception is thrown, and assert that list of Executable’s don’t throw an exception.

Catch an exception with assertThrows

JUnit5 includes an Assertion that you can use to verify thrown exceptions. The method takes two parameters: the type of
exception you expect and an Executable. The executable can be a Lambda expression, method reference, or implementation of the
Executable interface.

In the following example, we catch the exception the Car class throws and verify the message inside the exception is what we
expected it to be.

1
2
3
4
5
6
7
8
9
@Test
void throwsAnException() {
    Car car = new Car();
    RuntimeException exception = Assertions.assertThrows(RuntimeException.class, () -> {
        car.throwException();
    });

    Assertions.assertEquals("Something exception happened", exception.getMessage());
}

The test won’t fail if a subtype of the exception is thrown.

Catch a specific exception with assertThrowsExactly

If you want to verify that a specific exception is thrown, you will have to use assertThrowsExactly. In the following
example, we call a method that throws an EOFException. If the method throws any other exception, the test will fail.

1
2
3
4
5
6
7
8
9
@Test
void throwsAnExactlyEOFException() {
    Car car = new Car();
    EOFException eofException = Assertions.assertThrowsExactly(EOFException.class, () -> {
        car.throwsEOFException();
    });

    Assertions.assertEquals("Reached end of file", eofException.getMessage());
}

Verifying a specific exception is not thrown with assertDoesNotThrow

Yes, any execution thrown from a test method would cause a test to fail. There are cases where it can be handy to
explicitly verify an exception is not thrown.

1
2
3
4
5
@Test
void DoesNotThrowAnException() {
    Car car = new Car();
    Assertions.assertDoesNotThrow(() -> car.doesNotThrowAnException());
}

Using assertAll to verify multiple Executables

JUnit also offers an Assertion to verify that multiple Executables don’t throw an exception.

In the following example, we pass a list of Executables to the assertAll method that will verify that none of the lambda’s will
throw an exception.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
@Test
void noneThrowAnException() {
    Car carOne = new Car();
    Car carTwo = new Car();
    Car carThree = new Car();
    List<Executable> executables = new ArrayList<>();

    executables.add(() -> {
        carOne.doesNotThrowAnException();
    });
    executables.add(() -> {
        carTwo.doesNotThrowAnException();
    });
    executables.add(() -> {
        carThree.doesNotThrowAnException();
    });

    Assertions.assertAll(executables.stream());

}

Conclusion

This article looked at different ways to catch exceptions and verify their content. We also looked at two
cases that verify no exception is thrown.

Further reading

More about testing in Java:

  • Setting the order of Tests in JUnit5 and JUnit4
  • Run JUnit5 Tests in Parallel
  • Mock final classes and methods with Mockito

Понравилась статья? Поделить с друзьями:
  • Тест на ошибки текст
  • Тест виндовс на ошибки
  • Тест на ошибки сознания
  • Тест видеопамяти nvidia на ошибки
  • Тест видеокарты на ошибки nvidia