你如何模拟Throwable对象?

时间:2016-09-06 03:17:29

标签: java spring junit mockito

我想为我的应用程序编写Junit测试以处理错误方法,它看起来像这样

public void myHandlingError(Throwable t) {//content}

我想模拟Throwable对象,但我找不到任何示例。 这就是我在想的......

   public void myHandlingErrorTest(){
       Throwable t = new Exception();
       myClass.myHandlingError(t);
       .
       .
       .

任何建议都将不胜感激!

2 个答案:

答案 0 :(得分:7)

术语 mock 以某种方式暗示您使用模拟框架(如EasyMock)来创建您正在寻找的对象。但对于表示很少需要的异常的对象。你看,异常通常是在“输入错误”上创建的。

我的测试通常做的是:将一些“坏”输入驱动到一个类中;然后期望抛出某个异常。我的测试捕获该异常,并检索该异常的一个或多个属性;例如它的消息(使用断言验证)。

而且,另一方面:例外是您在生产代码中使用 new 创建的(大多数情况下)。因此,无论如何都没有简单的方法来嘲笑它。并为异常创建一个工厂,并使用依赖注入...听起来有点矫枉过正。你看,关于异常的好处是:在大多数情况下,代码是关于:“抛出的错误输入”。所以你只是提供了错误的输入,除了在测试中抛出异常以进一步验证。

在您的情况下,您正在测试实际接收throwable / exceptions对象的代码作为参数;在这里,您可以选择开始使用的方法 - 在测试中创建对象并将其传递给“处理程序”。

答案 1 :(得分:1)

要回显GhostCat's excellent answer,你不应该使用模拟异常或throwable。这有几个原因:

  • 例外是一种数据对象:异常在协作者之间携带一段数据,而不是作为协作者。数据对象通常很难模拟,许多get方法存根(对于可变数据对象更是如此,其中set需要使用匹配的副作用进行模拟)。由于数据对象通常没有依赖关系和稳定的实现,因此在测试中使用实际类的缺点很少。
  • Throwable有一些难以模拟的系统提供的方法,如fillInStackTrace。你不应该做模拟这样的事情。
  • Throwable还有一些不可能模拟的final方法,例如addSuppressedgetSuppressed。因为它们是最终的,所以EasyMock和Mockito不能使用动态代理来覆盖它们,因此,即使尝试模拟这些方法,您也必须使用PowerMock或其他一些字节码重写模拟工具。 / LI>
  • 您可以创建和传入各种现有的,易于实例化且经过良好测试的系统例外,包括IllegalArgumentExceptionNullPointerException,甚至RuntimeException本身。
  • Throwable,Exception和RuntimeException是为子类化而设计的,所以如果你想用自定义子类进行测试,你可以很容易地在测试中创建一个真正嵌套的Exception或Throwable子类。

交互所关联的非数据对象的模拟保留给您的SUT或MUT的一般合同,并使用真实对象或输入作为您的throwable和例外。