有时,你想测试一个类方法,并且你想对超类方法的调用做一个期望。我没有找到使用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()");
}
}
然后,在你的 JMockit 中使用FooTest.java
你可以验证你实际上是在调用Bar
from Foo
。
@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<Bar>() {
@Mock
public void bar() {
barCalled = true;
System.out.println("mocked bar");
}
};
Foo foo = new Foo();
foo.bar();
Assert.assertTrue(mockBar.barCalled);
}
不需要@MockClass注解的静态类,由MockUp类代替。
我不认为我会模拟一个超级调用 - 我觉得这种行为是类本身行为的一部分,而不是依赖项的行为。模拟总是感觉它应该与依赖关系比其他任何事情都更重要。
你有一个很好的例子来说明你想模拟的那种电话吗?如果您想模拟这样的调用,是否值得考虑组合而不是继承?
在 Animated Transitions 示例测试套件中,有几个使用 JMockit 期望 API 的测试可以做到这一点(即指定超类方法的预期调用)。例如,FadeInTest测试用例。
不,没有办法用jMock 模拟超类方法。
但是,有一个快速而肮脏的解决方案可以解决您的问题。假设您有 A 类和 B 类扩展 A。您想在 B 上模拟方法 Aa()。您可以在测试代码中引入 C 类扩展 B 并覆盖方法 Ca()(只需调用 super,或返回 null、id不要紧)。在那个模拟 C 之后,在任何地方使用模拟,在那里你会使用 B。
拦截一个超级调用太细粒度了。不要过度隔离。