首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JMockit:重写@JMockit类

JMockit:重写@JMockit类
EN

Stack Overflow用户
提问于 2015-05-29 21:10:40
回答 2查看 3.5K关注 0票数 2

我有一个内部StreamGobbler类,其中包含7个方法。我正在寻找一种默认情况下模拟所有方法的快速方法,但是重写一个名为getOutput()的方法(例如,部分模拟)。

(为清晰起见未显示完整代码)

代码语言:javascript
复制
public class StreamGobbler extends Thread
{
    public String getOutput() 
    public void run()
}

我想要的是结合使用@ getOutput注释和MockUp来部分模拟getOutput方法,但在所有其他方法上保留所有的“默认”模拟代码。在关于部分模拟的文档中,它指出,如果使用MockUp,所有非@Mock方法都保留它们的正常功能。有时候这很好,但这不是我想要的。

这类似于JMockit:@Mocke和MockUp在同一个测试中的组合的问题,但我不能只看方法计数。

如果我有这样的测试设置:

代码语言:javascript
复制
@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中添加@重写注释,它不会有帮助(而且Eclipse会抱怨它)

处理这件事最好的方法是什么?在此测试方法之外使用静态类?

使用JMockit 1.17和TestNG

总之,如何使StreamGobbler中的每个方法都被模拟(就像@ summary一样),但部分地覆盖一个方法(而不是自己在MockUp中手动完成?)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-02 16:03:36

满足给定约束的完整示例代码:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2015-05-29 21:38:48

首先,由于您正在创建MockUp类的匿名子类,所以使用@重写注释肯定是不合适的。您提供的那些方法不属于MockUp类,而是属于您所提供的泛型。

稍后,在运行时(通过一些令人印象深刻的过程(基于我所读到的这里,我假设是AOP)),您在该类中创建的实例将使用您提供的方法签名而不是它自己的方法签名。

在更深入地阅读了模拟类上的API以及从JMockit开始了页面获得一些信息之后,我认为您的问题在一个完全不同的领域。如果您有其他测试方法,它们将干扰此方法。

您所得到的错误是:“已经为StreamGobbler类型声明了一个StreamGobbler实例,通过在此测试方法的参数中调用模拟的注释,并试图用相同的泛型声明另一个MockUp实例,您违反了JMockit的规定。”我将检查是否在测试方法之外创建一个实际的MockUp of StreamGobbler,如果是这样的话(1)如果您想使用它,不要在方法中重新声明MockUp的另一个实例,而是继续使用模拟的注释;或者(2)如果您不想使用它,并且您想重新声明MockUp包装StreamGobbler的一个新实例,不要在测试方法的参数中使用模拟的注释,而是保留MockUp实例化。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30539136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档