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

发布于 2024-09-24 04:49:10 字数 834 浏览 6 评论 0原文

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

@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 文档,他们只使用 RuntimeException,是不是不可能用 Mockito 从模拟对象中抛出已检查的异常?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

哀由 2024-10-01 04:49:10

检查 Java API 中的 列表
get(int index) 方法声明为仅抛出扩展 RuntimeExceptionIndexOutOfBoundException
您试图告诉 Mockito 抛出异常 SomeException(),该异常无法由该特定方法调用抛出

进一步澄清。
List 接口不提供get(int index) 方法抛出一个已检查的异常,这就是 Mockito 失败的原因。

当您创建模拟列表时,Mockito 将使用List 的定义.class 来创建其模拟。

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

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

Check the Java API for List.
The get(int index) method is declared to throw only the IndexOutOfBoundException which 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.

To clarify further.
The List interface 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.

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.

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.

暖树树初阳… 2024-10-01 04:49:10

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

以下操作(并且不会抛出 MockitoException 但实际上根据此处的要求抛出已检查的 Exception):

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

例如,使用 BDDMockito可以执行 简单的 Mockito 将使用 doAnswer 方法

A workaround is to use a willAnswer() method.

For example the following works (and doesn't throw a MockitoException but actually throws a checked Exception as required here) using BDDMockito:

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

The equivalent for plain Mockito would to use the doAnswer method

潦草背影 2024-10-01 04:49:10

Kotlin 有一个解决方案:

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

给出的来自哪里

导入 org.mockito.BDDMockito.given

There is the solution with Kotlin :

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

Where given comes from

import org.mockito.BDDMockito.given

Hello爱情风 2024-10-01 04:49:10

请注意,一般来说,Mockito 确实允许抛出已检查的异常,只要异常在消息签名中声明即可。例如,假设

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

interface Foo {
  Bar frob() throws BarException
}

这样写是合法的:

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

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

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

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

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

Checked exception is invalid for this method!
Invalid: QuxException

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

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

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:

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 this checked exception isn't valid for this method.

遥远的她 2024-10-01 04:49:10

这在 Kotlin 中对我有用:

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

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

This works for me in Kotlin:

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

Note : Throw any defined exception other than Exception()

成熟稳重的好男人 2024-10-01 04:49:10

对于mockito,你可以使用

when(myObject.myFunction(arg1)).thenAnswer(i -> {throw new Exception("custom test exception");});

For mockito, you can just use

when(myObject.myFunction(arg1)).thenAnswer(i -> {throw new Exception("custom test exception");});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文