Почему Mockito.when(...). ThenThrow(...) выбрасывают прямо ошибку

У меня есть следующий код:

@Mock
private B b;

@InjectMocks
private A a;

@Test(expected = IOException.class)
public void test() {
    when(b.doSomething())
        .thenThrow(IOException.class);

    a.doSomethingWithB();
}

public class A {
    private B b;

    @Autowired
    public a(B b) {
        this.b = b
    }

    public boolean doSomethingWithB() {
        b.doSomething();
    }
}

На самом деле, этот тест не работает правильно, когда я отлаживаю его, thenThrow линия возвращает IOExceptionи на самом деле, это никогда не будет продолжаться a.doSomethingWithB(),

Моя версия Mockito - 2.19.1.

Спасибо за ваши ответы.

3 ответа

Метод B#doSomething() не может выдать IOException, поскольку он не является частью своей подписи. Вот почему Mockito не позволяет вам делать thenThrow(IOException.class),

Вы можете увидеть это, если посмотрите на трассировку стека неудачного теста:

java.lang.Exception: Unexpected exception, expected<java.io.IOException> but was<org.mockito.exceptions.base.MockitoException>

    at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
    at org.mockito.internal.junit.JUnitRule$1.evaluateSafely(JUnitRule.java:52)
    at org.mockito.internal.junit.JUnitRule$1.evaluate(JUnitRule.java:43)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    ....
Caused by: org.mockito.exceptions.base.MockitoException: 
Checked exception is invalid for this method!

Проблема в том, что ваш издевательский объект b не впрыскивается в объект a, Для введения этого поддельного объекта b в a в этом тестовом классе, вы должны аннотировать свой тестовый класс с любым из них @RunWith(MockitoJUnitRunner.class) или же Mockito.initMocks(this),

Правильное решение - использовать:

doThrow(IOException.class).when(b).doSomething();

вместо:

when().thenThrow

(Проверил это с Mockito 1.10.19и это работает, но с 2.19.0это не работает)

Другие вопросы по тегам