Страницы

Поиск по вопросам

суббота, 11 января 2020 г.

Тестирование потоков перехват исключений java

#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() { CompletableFuture future = 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); });

Комментариев нет:

Отправить комментарий