java 使用 JUnit 测试受保护的方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35186648/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 23:50:48  来源:igfitidea点击:

Testing protected method with JUnit

javareflectionjunit

提问by David DeMar

I am testing a method which is protected. In my test case I've used Reflectionto access the method but I am not exactly sure whether I am doing it in a right way.

我正在测试一种方法,它是protected. 在我的测试用例中,我曾经Reflection访问过该方法,但我不确定我是否以正确的方式执行此操作。

Method to be tested:

测试方法:

protected void checkORCondition( Map<String, Message> messagesMap ) throws EISClientException
{
    Message message = containsAMessageCode(getMessageCodes(), messagesMap);
    if(message!=null)
    {
        throw new EISClientException("One of the specified message code matched returned errors." + 
                message.getMessageCode() + ": " + message.getMessageType() + ": " + message.getMessageText());

    }
}

JUnit test case:

JUnit 测试用例:

@Test
public void testcheckORCondition() throws Exception {
    Class clazz = MessageToExceptionPostProcessFilter.class;
    Object object = clazz.newInstance();

    Method method = clazz.getDeclaredMethod("checkORCondition", new Class[]{Map.class});
    method.setAccessible(true);

    String string = new String();
    string = "testing";

    Message message = new Message();
    message.setMessageCode("200");

    Map<String, Message> map = new HashMap<String, Message>();
    map.put(string, message);

    assertEquals("testing", string);
    assertEquals("200", message.getMessageCode());  
}

My JUnit passes but not sure if it going inside the method.

我的 JUnit 通过了,但不确定它是否在方法内部。

回答by Sheetal Mohan Sharma

Best way is to put the protected methods under same package name under test. This will ensure that they are accessible. Check junit FAQ page http://junit.org/faq.html#organize_1

最好的方法是将受保护的方法放在相同的包名下进行测试。这将确保它们是可访问的。检查 junit 常见问题页面http://junit.org/faq.html#organize_1

回答by David DeMar

Using reflection to access protected methods from a unit test seems heavy handed. There are several easier ways to do this.

使用反射从单元测试访问受保护的方法似乎很笨拙。有几种更简单的方法可以做到这一点。

The easiest way would be to make sure your tests are in the same package hierarchy as the class you are testing. If that's not possible then you can subclass the original class and create a public accessor that calls the protected method.

最简单的方法是确保您的测试与您正在测试的类位于相同的包层次结构中。如果这是不可能的,那么您可以子类化原始类并创建一个调用受保护方法的公共访问器。

If it's a one-off case then it could even be as simple as making an anonymous class.

如果它是一次性的,那么它甚至可以像创建一个匿名类一样简单。

Class you want to test:

您要测试的类:

public class MessageToExceptionPostProcessFilter {

    protected void checkOrCondition(Map<String, Message> messagesMap) throws EISClientException {
        // Logic you want to test
    } 
}

And your test class:

还有你的测试课:

public class MessageToExceptionPostProcessFilterTest {
    @Test
    public void testCheckOrCondition() throws Exception {
        String string = "testing";

        Message message = new Message();
        message.setMessageCode("200");

        Map<String, Message> map = new HashMap<>();
        map.put(string, message);

        MessageToExceptionPostProcessFilter filter = new MessageToExceptionPostProcessFilter() {
            public MessageToExceptionPostProcessFilter callProtectedMethod(Map<String, Message> messagesMap) throws EISClientException {
                checkOrCondition(messagesMap);
                return this;
            }
        }.callProtectedMethod(map);

        // Assert stuff
    }
}

回答by Zbynek Vyskovsky - kvr000

It doesn't go inside the method as you don't call it. Use invoketo call it:

它不会进入方法内部,因为您没有调用它。用invoke它来称呼它:

method.invoke(this_parameter, new Object[]{ map });

Other than that, there is no good solution. One recommendation is to put the test into the same package and make it package visible, but there are lot of cons as the method will not be visible by inherited classes.

除此之外,没有什么好的解决办法。一种建议是将测试放在同一个包中并使其包可见,但有很多缺点,因为该方法不会被继承的类可见。

I believe the way you chose is good one.

我相信你选择的方式是好的。

回答by bmargulies

Use a mocking library to create a subclass as part of your test.

使用模拟库创建子类作为测试的一部分。