簡體   English   中英

使用 JUnit 測試受保護的方法

[英]Testing protected method with JUnit

我正在測試一種protected的方法。 在我的測試用例中,我使用Reflection來訪問該方法,但我不確定我是否以正確的方式執行此操作。

測試方法:

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
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());  
}

我的 JUnit 通過了,但不確定它是否在方法內部。

最好的方法是將受保護的方法放在相同的包名下進行測試。 這將確保它們是可訪問的。 檢查 junit 常見問題頁面http://junit.org/faq.html#organize_1

使用反射從單元測試訪問受保護的方法似乎很笨拙。 有幾種更簡單的方法可以做到這一點。

最簡單的方法是確保您的測試與您正在測試的類位於相同的包層次結構中。 如果這是不可能的,那么您可以子類化原始類並創建一個調用受保護方法的公共訪問器。

如果它是一次性的,那么它甚至可以像創建一個匿名類一樣簡單。

您要測試的類:

public class MessageToExceptionPostProcessFilter {

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

還有你的測試課:

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
    }
}

它不會進入方法內部,因為您沒有調用它。 使用invoke調用它:

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

除此之外,沒有什么好的解決辦法。 一種建議是將測試放在同一個包中並使其包可見,但有很多缺點,因為該方法不會被繼承的類可見。

我相信你選擇的方式是好的。

確保單元測試用例的包名稱與實際代碼所在的位置相同。 這將允許受保護的方法能夠在單元測試用例中正確訪問。

使用模擬庫創建子類作為測試的一部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM