我有一个内部StreamGobbler类,里面有7个方法。
我正在寻找一种默认模拟所有方法的快捷方法,但是覆盖一个名为getOutput()
的方法(例如Partial Mocking)。
(为清晰起见,未显示完整代码)
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中自己手动完成?)
答案 0 :(得分:1)
满足给定约束条件的完整示例代码:
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);
}
答案 1 :(得分:0)
首先,由于您正在创建MockUp类的匿名子类,因此使用@Override注释肯定是不合适的。您提供的那些方法不属于MockUp类,而是属于您提供的通用。
稍后在运行时期间(通过一些令人印象深刻的过程(基于我读到的here,我假设AOP))你在这个类中创建的实例将使用你提供的方法签名而不是它自己的
在更详尽地阅读Mock课程上的API以及从JMockit's Getting Started页面获取一些信息之后,我认为您的问题完全在于另一个领域。如果您有其他测试方法,他们将干扰此方法。
您得到的错误是:“已经为类型 StreamGobbler 声明了MockUp实例,并且在此测试方法的参数中调用了 Mocked 注释和试图用相同的泛型声明另一个MockUp实例,你违反了JMockit的规定。“ 我会检查你是否在测试方法之外创建一个实际的StreamGobbler MockUp,如果是这样的话(1)如果你想使用它,不要在方法中重新声明另一个MockUp实例,而是继续使用Mocked注释或者(2)如果你不想使用它并且你想重新声明一个包装StreamGobbler的MockUp的新实例,不要在测试方法的参数中使用Mocked注释,而是保持MockUp实例化。