使用Mockito验证是否调用了super.method()

19

首先,我想说我正在使用遗留代码,无论我想怎样改变它,都不能改变。

既然这样了,我现在要做的是验证一个 super.method() 是否被调用。 这是我试图用 Mockito/Junit 进行测试的特定内容:

class foo extends JApplet(){

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

如果没有调用超级方法,通常像这样的内容就足够在测试用例中使用:

verify(foo).destroy();

我曾经看到过这个问题被问了几次,通常的回答是“继承不好,改变你的代码”,但很不幸,我无法这样做。有人知道我可以用哪些框架或小技巧来测试吗?

非常感谢 - 我知道这是一个棘手的问题!


有没有一些测试的小技巧?你能否暂时更改你的代码?在super.destroy()中打印一些内容到控制台。你是否可以访问源代码? - Josh
很遗憾,修改源代码是绝对不可能的。 - DeaIss
4个回答

6
你可以重构代码,将调用super方法的部分提取到其他方法中,例如:
      class foo extends JApplet(){

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

然后进行验证:
verify(foo).callSuperDestroy();

4
这不是很有帮助。在我看来,当你知道该方法已经经过测试时,应该验证对该方法的调用。如果要验证对callSuperDestroy的调用,则还必须测试callSuperDestroy,这可能与在原始设计中执行它一样昂贵。 - JeanValjean
这是我能够验证间谍调用顺序的唯一方法,其中一个调用从该方法的覆盖中调用了超级方法。 - Alwyn Schoeman
这是我们在工作中的做法。有时候我们需要重构一些代码以使其可测试。 - Airwavezx
1
但是,如果这样做,最终你将无法验证是否调用了super的callSuperDestroy方法。 - strok_777

3
您实际上需要测试的是调用super方法后产生的影响是否仍然成立。通过调用super方法来实现这一点最简单,但这只是设计细节而已。
因此,建议您: 1. 为超级方法编写一个测试。 2. 为您的子方法编写一个测试,并在该测试中调用同一类中超级方法的测试(可以通过直接调用或继承测试来实现)。

2

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

先尝试 John B 的答案,似乎比我的建议好得多 :) - MrBackend
这正是我计划要做的事情 - 但我不确定是否有自定义的ClassLoader应用程序。打算手动编辑applet.java并让eclipse指向它。当然,说起来容易做起来难,我会先看看powermock。 - DeaIss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接