如何使用JUnit和JMock测试抽象类的受保护方法

时间:2011-12-04 13:15:05

标签: java unit-testing junit jmock

我有这样的情况 - 我有界面(比如MyInterface)和简单的部分实现(AbstractMyInterface)。后者添加了一些我想测试的受保护方法。

目前,我只是手工编写一个扩展AbstractMyInterface的模拟对象,并将受保护的方法导出为public。有没有更简单的方法 - 例如使用JMock +脚本?

3 个答案:

答案 0 :(得分:7)

使用JUnit测试受保护的方法时,我看不出任何问题。只要测试的包结构镜像源树结构,除了private之外的方法对于测试是可见的。

当然,如果要测试的实现是抽象的,那么你必须自己创建测试类的正常子类(或者如果适合你的目的,可以通过一些模拟库来实现)。同样在这种情况下,不需要为调用受保护的可见性方法创建公共方法层。仅对于私有方法,此策略不起作用。但无论如何,经常需要测试私有方法是设计问题的标志。

例如: 要测试的类位于src / mypackage / AbstractClass.java 打包mypackage;

/** This could as well implement some interface, 
    but that does not change a thing */
public class AbstractClass {
    protected int returnsOne() {
        return 1;
    }
}

测试哪个位于tests / mypackage / AbstractClassTest.java

package mypackage;

import org.junit.Test;

import static junit.framework.Assert.assertEquals;

public class AbstractClassTest {
    @Test
    public void returnsOneReturnsOne() {
        AbstractClass instanceToTest = new AbstractClassTestable();
        assertEquals(1, instanceToTest.returnsOne());
    }
}

/** This is needed, because we cannot construct abstract class directly */
class AbstractClassTestable extends AbstractClass {
}

答案 1 :(得分:3)

只是一个建议,

如果我们不测试受保护的方法怎么办?我们可以使用公共方法来覆盖那些受保护的方法吗?

如果没有,是因为受保护的方法太复杂,重构将复杂的东西提取到一个新的对象,它提供了公共接口,在一些公共方法中只留下一个私有对象。

测试稍后将在新对象上。

blog post可能会有所帮助。

答案 2 :(得分:0)

您可以为接口(或抽象类)创建一个抽象的测试用例。然后创建一个具体的测试用例,扩展您的抽象测试用例,用于接口(或抽象类)的每个具体实现。