#java #многопоточность #исключения #тестирование
Мы тестируем код и знаем, что у нас должно вывалиться исключение. К примеру мы тестируем
итератор и знаем, что больше элементов нету и если мы вызовем next (), тогда получим
NoSuchElementException, и чтобы всё было нормально мы пишем:
@Test(expected = NoSuchElementException.class)
public void shoulThrowNoSuchElementException() {
it = new Iteratorrmatrixmass(new int[][]{});
it.next();
}
У нас есть несколько потоков и один из потоков должен выбросить исключение OptimisticException:
@Test (expected = OptimisticException.class)
public void update() throws InterruptedException {
Base base = new Base(1, 1, "12321");
Base base1 = new Base(1, 2, "");
СacheBase data = new СacheBase();
data.add(base);
Thread r1 = new Thread(new Update(data, base1), "r1");
Thread r2 = new Thread(new Update(data, base1), "r2"); // здесь должна быть
OptimisticException.class
r1.start();
r2.start();
r1.join();
r2.join();
System.out.println(base.getVersion());
}
Но в этом случае (expected = OptimisticException.class) эта надпись нам не помогла,
в консоли всё равно вылазит надпись:
Exception in thread "r2" ru.job4j.blockhash.OptimisticException: Объект уже обновлён
до текущей версии, в обновлении отказано
Я полагаю из-за того, что это исключение выскакивает не в основном потоке. Что сделать
чтобы тестирование прошло успешно?
Ответы
Ответ 1
Есть такой "костыльный", но рабочий вариант : @Test public void test() { CompletableFuturefuture = CompletableFuture.runAsync(() -> { throw new OptimisticException("Optimistic Exception"); // ваш runnable код }); assertThatThrownBy(future::get) .hasCauseExactlyInstanceOf(OptimisticException.class) .hasMessageContaining("Optimistic Exception"); } Как это работает : Создается лямбда, которая выполняется когда вызывается метод get. Затем перехватывается ошибка и из нее достается исключение, которое выкинулось в вашем коде. P.S библиотека для ассертов - AssertJ Ответ 2
Для того, что бы тест выполнился вам надо бросить исключение в текущем потоке. Чтобы обработать исключение, возникающее в потоках надо в основном потоке установить обработчик Thread.setDefaultExceptionHandler((t, e) -> { throw new OptimisticException(e); });
Комментариев нет:
Отправить комментарий