如何存根类的私有方法在测试由Mockito



假设我们有一个java类SomeClass

public class SomeClass {
    private boolean isMethod() {
        return false;
    }
    public void sendRequest(String json, String text) {
        int messageId;
        if (isMethod()) {
            messageId = getMessageId(json);
            sendMessage(messageId, text);
        } else {
            throw new IllegalArgumentException();
        }
    }
    private void sendMessage(int messageId, String text) {
    }
    private int getMessageId(String text) {
        Pattern p = Pattern.compile("messageId=(\d+)&");
        Matcher m = p.matcher(text);
        if (m.find()) {
            return Integer.valueOf(m.group(1));
        }
        return 0;
    }
}

不要注意方法的名字,它们都是可选的。

  • 我想单独测试sendRequest(String json, String text)方法。
  • 我想存根isMethod()getMessageId(json)方法,并验证sendMessage(messageId, text)方法被调用。
  • 我需要确保getMessageId(json)返回25,isMethod()返回true,无论给定哪个参数值。

这可以通过powermockit框架实现。

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(SomeClass.class)
public class SomeClassTest {
    private SomeClass someInstance;
    @Before
    public void setUp() throws Exception {
        someInstance = PowerMockito.spy(new SomeClass());
    }
    @Test
    public void sendRequest() throws Exception {
        String json = "JSON";
        String text = "Some text";
        int messageId = 1;
        PowerMockito.doReturn(true).when(someInstance, "isMethod");
        PowerMockito.doReturn(messageId).when(someInstance, "getMessageId", json);
        someInstance.sendRequest(json, text);
        PowerMockito.verifyPrivate(someInstance).invoke("isMethod");
        PowerMockito.verifyPrivate(someInstance).invoke("getMessageId", json);
        PowerMockito.verifyPrivate(someInstance).invoke("sendMessage", messageId, text);
    }
}

除了在这个答案中所说的内容之外,我还要补充一点,测试是否调用私有方法的愿望表明您正在测试implementation而不是public contract of a class。这不是一个最佳的想法,因为它使重构变得更加困难。重构的思想是,你可以在不违反契约的情况下改变代码的内部工作方式。单元测试可以帮助您确保在更改implementation时不会对contract引入任何更改。

因此,在您的情况下,更好的选择是重构您的代码,以便您的测试调用公共方法并根据返回值验证结果

相关内容

  • 没有找到相关文章

最新更新