【问题标题】:Verifying super.method() is called using Mockito使用 Mockito 调用验证 super.method()
【发布时间】:2013-12-11 15:45:32
【问题描述】:

首先我想说的是,我正在使用遗留代码,无论我多么想更改它都无法更改。

除此之外,我要做的是验证是否调用了 super.method()。这就是我想用 Mockito/Junit 测试的具体内容:

class foo extends JApplet(){

       public void destroy(){
          super.destroy();
 }
}

如果测试用例不是被调用的超级方法,通常这样的事情就足够了:

verify(foo).destroy();

我已经看到这个问题被问了几次,通常回答是“继承不好,更改你的代码”,不幸的是我根本做不到。有没有人知道我可以做任何框架或小技巧来测试这个?

提前致谢 - 我知道这是一个棘手的问题!

【问题讨论】:

  • 测试的小技巧?您可以临时更改您的代码吗?在 super.destroy() 中的控制台上打印一些东西。您可以访问源代码吗?
  • 不幸的是,更改源代码完全没有问题。

标签: java testing junit mockito super


【解决方案1】:

您可以重构代码以在其他方法中调用超级方法,例如:

      class foo extends JApplet(){

       public void destroy(){
          callSuperDestroy();
       }
       public void callSuperDestroy(){
           super.destroy();
       }}

然后验证:

verify(foo).callSuperDestroy();

【讨论】:

  • 这没有帮助。我认为,一旦您知道该方法已经过测试,就应该验证对该方法的调用。如果验证了对callSuperDestroy 的调用,则必须同时测试callSuperDestroy,这可能与在原始设计中执行此操作一样昂贵。
  • 这是我可以验证对间谍的调用顺序的唯一方法,其中一个调用从该方法的覆盖中调用了超级方法。
  • 这就是我们在工作中的做法。有时我们需要重构一些代码以使其可测试。
  • 但是你最终将无法验证 super 是否被调用到 callSuperDestroy
【解决方案2】:

你真正需要测试的是调用超级方法的效果仍然成立。实现这一点的最简单方法是调用超级方法,这一事实只是一个设计细节。

考虑到这一点:

  1. 为超级方法编写测试。
  2. 为您的子方法编写一个测试,并在该测试中为同一类调用该超级方法的测试(通过直接调用或通过对测试进行子类化)。

【讨论】:

    【解决方案3】:

    JMockit 似乎可以做到这一点。看看这篇文章:

    Powermock - mocking a super method invocation

    【讨论】:

      【解决方案4】:

      我还没有尝试过,但是否可以创建一个自定义 ClassLoader 来覆盖仅加载 JApplet 类?然后您可以创建自己的 JApplet,它会记住是否调用了 destroy()。

      【讨论】:

      • 先试试 John B 的回答 - 似乎比我的建议好得多 :)
      • 这正是我打算做的——但我不确定是否有自定义的 ClassLoader 应用程序。计划手动编辑 applet.java 并让 eclipse 指向它。说的容易,做的当然好,我先看看powermock。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-07
      相关资源
      最近更新 更多