繁体   English   中英

如何在Mockito中测试私有的类方法

[英]How to stub private methods of class under test by Mockito

假设我们有一个名为SomeClass的java类

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。

这可以通过PowerMockito框架实现。

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 classpublic contract of a class 这不是一个最佳的想法,因为它会使您的重构更加困难。 重构的想法是,您可以在不违反合同的情况下更改代码的内部工作方式。 并且您的单元测试可以帮助您确保在更改implementation ,您没有对contract任何更改。

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

Vanguard给出了正确的答案,但是使用Maven需要dependensies

<!-- https://mvnrepository.com/artifact/org.powermock/powermock-module-junit4 -->
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>2.0.0</version>
    <scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.powermock/powermock-api-mockito2 -->
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <version>2.0.0</version>
    <scope>test</scope>
</dependency>

暂无
暂无

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

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