【发布时间】:2019-10-27 19:27:10
【问题描述】:
我有这样的情况——我有接口(比如MyInterface)和简单的部分实现(AbstractMyInterface)。后者添加了一些我想测试的受保护方法。
目前我只是手动编写了一个模拟对象,它扩展了AbstractMyInterface 并将受保护的方法导出为公共的。有没有更简单的方法——例如使用 JMock+scripting?
【问题讨论】:
标签: java unit-testing junit jmock
我有这样的情况——我有接口(比如MyInterface)和简单的部分实现(AbstractMyInterface)。后者添加了一些我想测试的受保护方法。
目前我只是手动编写了一个模拟对象,它扩展了AbstractMyInterface 并将受保护的方法导出为公共的。有没有更简单的方法——例如使用 JMock+scripting?
【问题讨论】:
标签: java unit-testing junit jmock
我看不出用 JUnit 测试受保护的方法有任何问题。只要测试的包结构反映源树结构,私有以外的方法对测试都是可见的。
当然,如果要测试的实现是抽象的,您必须自己创建被测类的普通子类(或者如果更适合您的目的,可以通过一些模拟库来创建)。同样在这种情况下,无需为调用受保护的可见性方法而创建公共方法层。仅对于私有方法,此策略不起作用。但是通常需要测试私有方法无论如何都是设计问题的标志。
例如: 要测试的类位于 src/mypackage/AbstractClass.java 打包我的包裹;
/** This could as well implement some interface,
but that does not change a thing */
public abstract 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 {
}
【讨论】:
abstract 修饰符添加到您的 AbstractClass :)
instanceToTest 初始化为new AbstractClass(){};
只是一个建议,
如果我们不测试受保护的方法,我们可以使用公共方法来覆盖那些受保护的方法吗?
如果不是,是不是因为protected方法太复杂,重构把复杂的东西提取到一个新的对象中,它提供了公共接口,在一些公共方法中只留下旧对象一个私有对象。
稍后将在新对象上进行测试。
这个blog post 可能会有所帮助。
【讨论】:
您可以为接口(或抽象类)创建一个抽象测试用例。然后为你的接口(或抽象类)的每个具体实现创建一个具体的测试用例,扩展你的抽象测试用例。
【讨论】: