我有一个内部StreamGobbler类,其中包含7个方法。
我正在寻找一种默认情况下可模拟所有方法的快速方法,但可以覆盖一个名为getOutput()
的方法(例如,部分模拟)。
(为清晰起见,未显示完整代码)
public class StreamGobbler extends Thread
{
public String getOutput()
public void run()
}
我想要的是将@Mocked注释与MockUp结合使用,以部分模拟getOutput方法,但在所有其他方法上保留所有“默认”模拟代码。在有关部分模拟的文档中,它指出如果使用MockUp,则所有非@Mock方法都将保留其正常功能。有时候那很棒,但这不是我想要的。
这与问题JMockit: @Mocke and MockUp combination in the same test相似,但是仅查看方法计数就无法摆脱。
如果我有这样的测试设置:
@Test
public void execute(@Mocked StreamGobbler sg)
{
new MockUp<StreamGobbler>()
{
String type = null;
@Mock
void $init(String type)
{
this.type = type;
}
@Mock
String getOutput()
{
if ("OUTPUT".equals(type))
{
return "test output";
}
else
{
return "";
}
}
}
}
我收到此错误
java.lang.IllegalArgumentException: Class already mocked
如果我尝试在MockUp中添加@Override批注,那么它无济于事(Eclipse对此很抱怨)
处理此问题的最佳方法是什么?在此测试方法之外使用静态类?
使用JMockit 1.17和TestNG
总之,如何模拟StreamGobbler中的每个方法(与@Mocked一样),但部分重写一个方法(无需自己在MockUp中手动进行处理?)
最佳答案
满足给定约束的完整示例代码:
public static class StreamGobbler extends Thread {
public StreamGobbler(String type) {}
public String getOutput() { return null; }
@Override public void run() {}
}
public static class TestedClass {
public String doSomething() throws InterruptedException {
StreamGobbler sg1 = new StreamGobbler("OUTPUT");
sg1.start();
StreamGobbler sg2 = new StreamGobbler("ERROR");
sg2.start();
sg1.join(5000);
sg2.join(5000);
String output1 = sg1.getOutput();
String output2 = sg2.getOutput();
return output1 + '|' + output2;
}
}
@Test
public void useStreamGobbler(@Mocked StreamGobbler sg) throws Exception {
new Expectations() {{
new StreamGobbler("OUTPUT").getOutput(); result = "test output";
new StreamGobbler("ERROR").getOutput(); result = "";
}};
String output = new TestedClass().doSomething();
assertEquals("test output|", output);
}