我可以模拟一个超类方法调用吗?

有时候,你想要测试一个类方法,并且你希望在调用超类方法时做一个期望。 我没有找到一种方法来使用easymock或jmock在java中做这个期望(我认为这是不可能的)。

有一个(相对)干净的解决方案,用超类方法逻辑创建一个委托,然后设置它的期望,但我不知道为什么以及何时使用该解决方案?任何想法/例子?

谢谢

好吧,如果你愿意,你可以。 我不知道你是否熟悉JMockit ,去看看吧。 目前的版本是0.999.17同时,我们来看看它……

假设以下类层次结构:

public class Bar { public void bar() { System.out.println("Bar#bar()"); } } public class Foo extends Bar { public void bar() { super.bar(); System.out.println("Foo#bar()"); } } 

然后,在您的FooTest.java使用JMockit,您可以validation您实际上是从Foo调用Bar

 @MockClass(realClass = Bar.class) public static class MockBar { private boolean barCalled = false; @Mock public void bar() { this.barCalled = true; System.out.println("mocked bar"); } } @Test public void barShouldCallSuperBar() { MockBar mockBar = new MockBar(); Mockit.setUpMock(Bar.class, mockBar); Foo foo = new Foo(); foo.bar(); Assert.assertTrue(mockBar.barCalled); Mockit.tearDownMocks(); } 

使用JMockit 1.22扩展@Cem Catikkas答案:

 @Test public void barShouldCallSuperBar() { new MockUp() { @Mock public void bar() { barCalled = true; System.out.println("mocked bar"); } }; Foo foo = new Foo(); foo.bar(); Assert.assertTrue(mockBar.barCalled); } 

不需要使用@MockClass注释的静态类,它将被MockUp类替换。

我不认为我会嘲笑一个超级调用 – 我觉得这个行为本身就是行为的一部分,而不是依赖行为。 模仿总是感觉它应该与依赖关系相比更重要。

你有一个很好的例子,你想要模拟出来的那种电话吗? 如果你想模拟这样的调用,是否值得考虑组合而不是inheritance?

在Animated Transitions示例测试套件中,使用JMockit Expectations API有几个测试可以做到这一点(即在超类方法上指定预期的调用)。 例如, FadeInTest测试用例。

不,没有办法用jMock模拟超类方法。

但是,您的问题有一个快速而肮脏的解决方案。 假设你有A类,B类扩展A.你想在B上模拟方法Aa()你可以在你的测试代码中引入C类扩展B并覆盖方法Ca()(只需调用super,或者返回null,id没关系)。 在那个模拟C之后,到处使用模拟,你在哪里使用B.

拦截超级电话太精细了。 不要过度孤立。