我有一个内部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);
}

07-26 03:40