2011-12-04 47 views
4

抽象类的如何测试protected的方法我也有这样的情况 - 我有接口(比如MyInterface)和简单的部分实现(AbstractMyInterface)。后者增加了一些我想测试的受保护的方法。使用JUnit和JMock的

目前我只是手工编写延伸AbstractMyInterface和出口的保护方法为公共模仿对象。有没有更简单的方法 - 例如使用JMock +脚本?

回答

6

我无法看到使用JUnit测试protected方法任何问题。只要测试包结构反映源树结构,除私有方法外,测试可见。

当然,如果执行测试是抽象的,你必须自己测试下创建类的子类正常(或者,如果你的目的更适合的通过一些嘲讽库这样做)。同样在这种情况下,不需要为调用受保护的可见性方法创建一层公共方法。只有私人方法这个策略不起作用。但无论如何,经常需要测试私有方法是设计问题的标志。

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

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

和测试它位于测试/ 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 { 
} 
+0

除了我有越来越多的未使用的存根在测试中,没有任何问题。 –

0

可以使抽象测试用例的接口(或抽象类)。然后做一个具体的测试用例,扩展你的抽象测试用例,以便为你的接口(或抽象类)的每个具体实现。

3

只是一个建议,

如果我们不测试受保护的方法,我们可以使用哪些公有方法来覆盖这些保护方法?

如果不是,是不是因为受保护的方法太复杂的,重构提取复杂的事情到一个新的对象,它提供的公共接口,而旧的对象只是一个私有对象在一些公共方法。

测试将在以后的新对象上进行。

blog post可能会有所帮助。

+0

否 - 受保护的方法非常简单,但它们都是公开API(简单发布/订阅模型的一部分)。该部分由公共方法使用,但测试它是否有效我需要访问受保护的部分。作为后 - 虽然我同意私人方法不应该被测试,但受保护的方法被其他人使用。 –

+0

公共方法需要访问由受保护方法包装的公共API,看起来这个类有两个任务。设计一个包装类来隐藏公共API,并设计一个用户类来使用包装提供的服务。所以,即使API将要改变,也不会损害可能充满逻辑的用户类。我从单元测试中学习了十年杂乱无章的C代码,如果它很难做单元测试,离开它,重构代码是一种简单而好的RoI方法。 –

+0

Chris Zheng:你可以证明对于使用发布订阅的简单代码吗?公共方法应该只注册/注销观察者,而受保护的方法只是触发各种事件(循环观察者设置和发送通知事件)。我没有看到解决方案会按照您描述的方式进行,并且不会违反KISS规则。 –