我想我可能在JMockit中发现了一个bug,但我想确认一下是不是真的有bug或者是否有我没有注意到的东西。
我有一个非常简单的类:
public class Dummy {
public void foo() {System.out.println("O");}
}
现在我有以下测试,每个测试中我都尝试模拟方法“foo”多次(每个测试都略有不同):
测试#1
@Test
public void test1() {
new MockUp<Dummy>() {
@Mock
public void foo(Invocation inv) {
System.out.println("A");
inv.proceed();
}
}
new MockUp<Dummy>() {
@Mock
public void foo(Invocation inv) {
System.out.println("B");
inv.proceed();
}
}
new Dummy().foo();
}
测试 #2
@Test
public void test2() {
mock("A");
mock("B");
new Dummy().foo();
}
private void mock(final String s) {
new MockUp<Dummy>() {
@Mock
public void foo(Invocation inv) {
System.out.println(s);
inv.proceed();
}
}
}
唯一的区别在于将模拟代码提取到不同的方法中。但结果是不同的...
测试#1输出:
B
A
B
O
这很奇怪,因为我根本不希望 A 出现。但无论如何,以下是第二个测试的输出:
B
A
A
A
...ad infinitum
第二个测试将因为StackOverflowError而失败。
这是一个bug还是我漏掉了什么?
更新(解决方案)
正如@Rogério提到的,这种行为是不可接受的。
那么如何覆盖模拟?像这样:
private MockUp<Dummy> mock;
@Test
public void test3() {
mockCorrectly("A");
mockCorrectly("B");
new Dummy().foo();
}
private void mockCorrectly(final String s) {
if (mock != null) {
mock.tearDown();
}
mock = new MockUp<Dummy> {
@Mock
public void foo(Invocation inv) {
System.out.println(s);
inv.proceed();
}
}
}
关于输出:
B
O
非常好 :)