java 如何验证在测试代码中捕获异常时,是否由模拟抛出异常?

dsf9zpds  于 2023-08-01  发布在  Java
关注(0)|答案(2)|浏览(127)

在Java/Junit/Mockito中,模拟异常相当容易(doThrow()等),并且当抛出异常而未捕获异常时也相当容易验证(assertThrows()等)。但是,如果使用doThrow成功模拟了异常,但随后在主代码中捕获了异常,测试如何知道它曾经抛出过呢?
考虑以下代码段:

  1. public void doFullOpeartion() {
  2. try {
  3. optionalService.blink();
  4. }
  5. catch (IOException exception) {
  6. // No operation needed
  7. }

字符串
测试代码如下:

  1. doThrow(IOException.class).when(mockOptionalService).blink();
  2. classUnderTest.doFullOperation();
  3. // ??? - how do we know that IOException was thrown


如果在主代码的catch块中有一些可以验证的代码,那么问题就没有意义了。但如果我们不呢?

btxsgosb

btxsgosb1#

我更喜欢tddavies的答案(只要验证mock被调用了--因为你知道调用它意味着它会抛出)。但这里有另一个解决方案,它可能使您试图Assert的内容更加明确。
doAnswer是更通用的Mockito原语,它可以返回值或抛出。在那里你可以只保留一个计数器。

  1. AtomicInteger blinkIOExceptions = new AtomicInteger();
  2. doAnswer(invocation -> {
  3. blinkIOExceptions.incrementAndGet();
  4. throw new IOException();
  5. }).when(mockOptionalService).blink();
  6. assertEquals(1, blinkIOExceptions.get());

字符串

hlswsv35

hlswsv352#

我不认为您可以检查异常是否真的被抛出,但是您可以验证您为抛出异常而被删除的方法是否真的被调用了。参见下面的示例,我们控制是否调用该方法,当它没有被调用时,测试失败:

  1. package org.example;
  2. import org.junit.jupiter.api.Test;
  3. import org.junit.jupiter.api.extension.ExtendWith;
  4. import org.mockito.InjectMocks;
  5. import org.mockito.Mock;
  6. import org.mockito.junit.jupiter.MockitoExtension;
  7. import java.io.IOException;
  8. import static org.mockito.Mockito.doThrow;
  9. import static org.mockito.Mockito.verify;
  10. class ToTest {
  11. private final InjectedClass injectedClass;
  12. ToTest(InjectedClass injectedClass) {
  13. this.injectedClass = injectedClass;
  14. }
  15. public void doIt(boolean callMethod) {
  16. try {
  17. if (callMethod) {
  18. injectedClass.mightThrow();
  19. }
  20. } catch (IOException e) {
  21. // ignore (this seems like a bad idea...
  22. }
  23. }
  24. }
  25. interface InjectedClass {
  26. void mightThrow() throws IOException;
  27. }
  28. @ExtendWith(MockitoExtension.class)
  29. public class AppTest {
  30. @Mock
  31. InjectedClass injectedClass;
  32. @InjectMocks
  33. ToTest toTest;
  34. @Test
  35. public void passingTest() throws IOException {
  36. doThrow(IOException.class).when(injectedClass).mightThrow();
  37. toTest.doIt(true);
  38. verify(injectedClass).mightThrow();
  39. }
  40. @Test
  41. public void failingTest() throws IOException {
  42. doThrow(IOException.class).when(injectedClass).mightThrow();
  43. toTest.doIt(false);
  44. verify(injectedClass).mightThrow();
  45. }
  46. }

字符串

展开查看全部

相关问题