Почему 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
это не работает)