使用JMockit模拟抽象类中的非公共静态方法?

7

我有以下的类:

public abstract class AbstractParent {
    static String method() {
        return "OriginalOutput";
    }
}

我想模拟这个方法。我决定使用JMockit。因此,我创建了一个模拟类:

public class MockParent {
    static String method() {
        return "MOCK";
    }
}

我的测试代码如下:

public class RealParentTest {

    @Before
    public void setUp() throws Exception {
        Mockit.redefineMethods( AbstractParent.class, MockParent.class );
    }


    @Test
    public void testMethod() {
        assertEquals(MockParent.method(),AbstractParent.method());
    }

}

很遗憾,这个测试显示AbstractParent返回的是"OriginalOutput"而不是"MOCK"。有什么想法吗?我做错了什么吗?我已经尝试将我的模拟类声明为抽象类,但没有效果。

编辑 注意,将该方法设置为public可以顺利运行测试...这很奇怪,因为使用JMockit时,你应该能够模拟任何范围的方法。

答案 只有模拟方法需要设置为public,你可以保留原始方法不变。


仅供经过谷歌搜索的人参考:接受的答案现在已过时,因为Mockit.redefineMethods已被弃用...我正在尝试找到正确的方法。 - Gareth Davis
2个回答

6
发现解决方法:您只需要将模拟方法公开(原始方法可以保持其原始可见性)即可。
我不知道为什么这种方法有效而原始方法无效(欢迎了解的人加入讨论),但您只需要简单地更改上面示例中的模拟类:
public class MockParent {
    public static String method() {
        return "MOCK";
    }
}

1
甚至在MockParent中也不必将其设置为静态。 - Cem Catikkas
1
jmockit 只关注公共方法。这使得您的模拟实现可以具有与源类中的方法不对应的内部方法。 - Kris Pruden
2
Mock方法需要是公共的原因是JMockit会修改被mock的方法,使其调用Mock方法。 也就是说,对原始方法的调用从该方法内部重定向到Mock方法。 因此,在插入调用的那个点上,Mock方法必须是可访问的。 - Rogério

4

显然,现在做这件事的新方法是使用MockUp<T>

new MockUp<AbstractParent>(){
    @Mock String method() {
        return "MOCK";
    }
};

assertEquals("MOCK" AbstractParent.method());

另一种选择是继续使用类似于MockParent的东西,并使用@MockClass注释。我自己没有这样做,因为另一个内联版本已经完成了工作。

我在一个示例中实现了这个github上的项目


原始的 AbstractParent.method()static 的。这种方式不能用于 static 方法。 - Adeel Ansari
3
好的,我会尽力进行翻译。以下是需要翻译的内容:@Adeel I beg to differ https://github.com/gid79/q224721-jmockit-non-public-methods - Gareth Davis
抱歉之前的评论,实际上我尝试过了,但它并没有真正起作用,后来我发现那是因为完全不同的原因。感谢提供示例,点个赞。 - Adeel Ansari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接