java – JMockit:如何使用新的模拟覆盖已经模拟过的方法?
作者:互联网
我想我可能在JMockit中发现了一个错误,但我想确认一下这是一个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出现.但无论如何,这是测试#2的输出:
B
A
A
A
...ad infinitum
测试#2将因StackOverflowError而失败.
这是一个错误还是我错过了什么?
更新(使用解决方案)
正如@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
太棒了:)
解决方法:
目前尚不清楚这里到底发生了什么;显然,在运行时,正在发生一些“链式嘲弄”.
真正的问题是两个测试都使用MockUp API做了一些无效的事情:他们在同一个测试中两次在同一个类中模拟相同的方法.只要它们模拟不同的方法/构造函数,就可以在同一个测试中为同一个类提供两个不同的模型.
由于JMockit不支持同一方法的多个同时模拟,因此未定义结果行为.
标签:java,mocking,jmockit 来源: https://codeday.me/bug/20190624/1282851.html