代码之家  ›  专栏  ›  技术社区  ›  Arthur Maltson

使用mockito从mocks中抛出选中的异常

  •  118
  • Arthur Maltson  · 技术社区  · 14 年前

    我试图让我的一个模拟对象在调用特定方法时抛出一个选中的异常。我正在尝试以下操作。

    @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 documentation ,它们只使用 RuntimeException ,是否不可能从具有mockito的模拟对象中抛出选中的异常?

    2 回复  |  直到 7 年前
        1
  •  162
  •   Rajath    12 年前

    检查Java API List . get(int)方法声明为只抛出扩展RuntimeException的IndexOutOfBoundexception。您试图告诉mockito抛出一个异常,该异常对于该特定方法调用所引发的异常无效。

    进一步澄清。列表接口不提供要从get()方法抛出的已检查异常,这就是Mockito失败的原因。创建模拟列表时,mockito使用list.class的定义创建其模拟。使用指定的行为 when(list.get(0)).thenThrow(new SomeException()) 与list.class中的方法签名不匹配,因此mockito失败。如果你真的想这样做,那就让莫基托扔一个 new RunTimeException() 或者更好地扔一个 new ArrayIndexOutOfBoundsException() 因为API指定这是唯一要抛出的有效异常。

        2
  •  45
  •   David Rawson B Aristide    7 年前

    解决方法是使用 willAnswer() 方法。

    例如,以下工作(并且不抛出 MockitoException 但事实上,抛出了一个检查 Exception 按此处要求)使用 BDDMockito :

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

    相当于普通mockito将使用 doAnswer 方法