简体   繁体   English

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

[英]How to test protected methods of abstract class using JUnit and JMock

I have such situation - I have interface (say MyInterface ) and simple partial implementation ( AbstractMyInterface ).我有这样的情况 - 我有接口(比如MyInterface )和简单的部分实现( AbstractMyInterface )。 The latter adds a few protected methods which I would like to test.后者添加了一些我想测试的受保护方法。

Currently I simply write by hand a mock object which extends AbstractMyInterface and export protected methods as public.目前我只是手工编写一个模拟对象,它扩展了AbstractMyInterface并将受保护的方法导出为公共。 Is there a simpler way of doing this - for example using JMock+scripting?有没有更简单的方法来做到这一点 - 例如使用 JMock+脚本?

I cannot see any problem with testing protected methods with JUnit.我看不出使用 JUnit 测试受保护方法有任何问题。 As long as package structure for tests mirrors source tree structure, methods other than private are visible for tests.只要测试的包结构反映了源树结构,测试就可以看到除私有之外的方法。

Of course if implementation to test is abstract, you have to create normal subclass of class under test by yourself (or do it via some mocking library if fits better for your purposes).当然,如果要测试的实现是抽象的,则您必须自己创建被测类的正常子类(或者,如果更适合您的目的,则通过一些模拟库来创建)。 Also in such a case, no need to create layer of public methods for just for calling protected visibility methods.同样在这种情况下,无需为调用受保护的可见性方法而创建公共方法层。 Only for private methods this strategy does not work.仅对于私有方法,此策略不起作用。 But often need to test private methods is sign of design problem anyway.但是经常需要测试私有方法无论如何都是设计问题的标志。

For example: Class to test located to src/mypackage/AbstractClass.java package mypackage;例如:要测试的类位于 src/mypackage/AbstractClass.java 包 mypackage;

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

And test which is located to tests/mypackage/AbstractClassTest.java和位于 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 {
}

Just a suggestion,只是一个建议,

What if we don't test the protected methods, can we use the public methods to cover those protected methods?如果我们不测试受保护的方法,我们可以使用公共方法来覆盖那些受保护的方法吗?

If not, is it because of the protected methods too complicated, refactor to extract the complicated things to a new object, which provides public interfaces, leaving the old object just one private object in some public methods.如果不是,是不是因为protected方法太复杂了,重构把复杂的东西提取到一个新的对象中,新对象提供公共接口,在一些公共方法中让旧对象只是一个私有对象。

The test will later be on the new object.稍后将在新对象上进行测试。

This blog post might be helpful.这篇博文可能会有所帮助。

you can make an abstract test case for the interface (or abstract class).您可以为接口(或抽象类)制作抽象测试用例。 then make a concrete test case that extends your abstract test case for each concrete implementation of your interface (or abstract class).然后制作一个具体的测试用例,为接口(或抽象类)的每个具体实现扩展抽象测试用例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM