Бросок проверен Исключения из mocks с Mockito

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

@Test(expectedExceptions = SomeException.class)
public void throwCheckedException() {
    List<String> list = mock(List.class);
    when(list.get(0)).thenThrow(new SomeException());
    String test = list.get(0);
}

public class SomeException extends Exception {
}

Однако это вызывает следующую ошибку.

org.testng.TestException: 
Expected exception com.testing.MockitoCheckedExceptions$SomeException but got org.mockito.exceptions.base.MockitoException: 
Checked exception is invalid for this method!
Invalid: com.testing.MockitoCheckedExceptions$SomeException

Глядя на документацию Mockito, они используют только RuntimeException, невозможно ли выкинуть проверенные Исключения из макета с Mockito?

Ответ 1

Проверьте Java API для списка. Метод get (int) объявлен для выброса только исключения IndexOutOfBoundException, которое расширяет RuntimeException. Вы пытаетесь заставить Mockito выдать исключение, которое недопустимо для этого конкретного вызова метода.

Чтобы уточнить дальше. Интерфейс List не предоставляет выброшенное исключение для метода get(), поэтому Mockito не работает. Когда вы создаете фиктивный список, Mockito использует определение List.class, чтобы создать его макет. Поведение, которое вы указываете с помощью when(list.get(0)).thenThrow(new SomeException()) не соответствует сигнатуре метода в List.class, поэтому Mockito завершается ошибкой. Если вы действительно хотите это сделать, то пусть Mockito сгенерирует new RuntimeException() или, что еще лучше, сгенерирует new ArrayIndexOutOfBoundsException() так как API указывает, что это единственное допустимое исключение, которое будет выброшено.

Ответ 2

Обходной путь должен использовать метод willAnswer().

Например, следующее работает (и не MockitoException но фактически выдает проверенное Exception как требуется здесь) с использованием BDDMockito:

given(someObj.someMethod(stringArg1)).willAnswer( invocation -> { throw new Exception("abc msg"); });

Эквивалент для простого Mockito будет использовать метод doAnswer