Java 使用 Mockito 从模拟中抛出已检查的异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3762047/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 04:33:58  来源:igfitidea点击:

throw checked Exceptions from mocks with Mockito

javamockingmockito

提问by Arthur Maltson

I'm trying to have one of my mocked objects throw a checked Exception when a particular method is called. I'm trying the following.

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

@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 {
}

However, that produces the following error.

但是,这会产生以下错误。

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

Looking at the Mockito documentation, they only use RuntimeException, is it not possible to throw checked Exceptions from a mock object with Mockito?

查看Mockito 文档,他们只使用RuntimeException,是否不可能使用 Mockito 从模拟对象中抛出已检查的异常?

采纳答案by John Engelman

Check the Java API for List.
The get(int index)method is declared to throw only the IndexOutOfBoundExceptionwhich extends RuntimeException.
You are trying to tell Mockito to throw an exception SomeException()that is not valid to be thrown by that particular method call.

检查 Java API 以获取List
get(int index)方法被声明为只抛出IndexOutOfBoundExceptionwhich extends RuntimeException
您试图告诉 Mockito 抛出一个异常SomeException(),该异常对于该特定方法调用无效

To clarify further.
The Listinterface does not provide for a checked Exception to be thrown from the get(int index)method and that is why Mockito is failing.
When you create the mocked List, Mockito will use the definition of List.class to creates its mock.

进一步澄清。
列表界面不提供用于检查异常从抛出get(int index)的方法,这就是为什么是的Mockito失败。
当您创建模拟的List 时,Mockito 将使用List.class的定义来创建它的模拟。

The behavior you are specifying with the when(list.get(0)).thenThrow(new SomeException())doesn't match the method signature in List API, because get(int index)method does not throw SomeException()so Mockito fails.

您使用 指定的行为与when(list.get(0)).thenThrow(new SomeException())List API 中的方法签名不匹配,因为get(int index)方法不会抛出SomeException()所以 Mockito 失败。

If you really want to do this, then have Mockito throw a new RuntimeException()or even better throw a new ArrayIndexOutOfBoundsException()since the API specifies that that is the only valid Exception to be thrown.

如果您真的想这样做,那么让 Mockito 抛出一个new RuntimeException()甚至更好的抛出一个,new ArrayIndexOutOfBoundsException()因为 API 指定这是唯一要抛出的有效异常。

回答by Deepak

A workaround is to use a willAnswer()method.

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

For example the following works (and doesn't throw a MockitoExceptionbut actually throws a checked Exceptionas required here) using BDDMockito:

例如,以下工作(并且不抛出 aMockitoException但实际上Exception根据需要抛出一个检查的here)使用BDDMockito

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

The equivalent for plain Mockito would to use the doAnswermethod

普通 Mockito 的等价物将使用该doAnswer方法

回答by Kevin ABRIOUX

There is the solution with Kotlin :

Kotlin 有解决方案:

given(myObject.myCall()).willAnswer {
    throw IOException("Ooops")
}

Where given comes from

给定的来源

import org.mockito.BDDMockito.given

导入 org.mockito.BDDMockito.given

回答by David Moles

Note that in general, Mockito doesallow throwing checked exceptions so long as the exception is declared in the message signature. For instance, given

请注意,一般而言,Mockito确实允许抛出已检查的异常,只要该异常在消息签名中声明即可。例如,给定

class BarException extends Exception {
  // this is a checked exception
}

interface Foo {
  Bar frob() throws BarException
}

it's legal to write:

写是合法的:

Foo foo = mock(Foo.class);
when(foo.frob()).thenThrow(BarException.class)

However, if you throw a checked exception not declared in the method signature, e.g.

但是,如果您抛出未在方法签名中声明的已检查异常,例如

class QuxException extends Exception {
  // a different checked exception
}

Foo foo = mock(Foo.class);
when(foo.frob()).thenThrow(QuxException.class)

Mockito will fail at runtime with the somewhat misleading, generic message:

Mockito 将在运行时失败,并显示一些误导性的通用消息:

Checked exception is invalid for this method!
Invalid: QuxException

This may lead you to believe that checked exceptions in general are unsupported, but in fact Mockito is only trying to tell you that thischecked exception isn't valid for this method.

这可能会让您认为检查异常通常不受支持,但实际上 Mockito 只是想告诉您检查异常对于此方法无效。

回答by Alok Gupta

This works for me in Kotlin:

这在 Kotlin 中对我有用:

when(list.get(0)).thenThrow(new ArrayIndexOutOfBoundsException());

当(list.get(0)).thenThrow(new ArrayIndexOutOfBoundsException());

Note : Throw any defined exception other than Exception()

注意:抛出 Exception() 以外的任何定义的异常