如何模拟在另一个私有方法内部调用的私有方法

时间:2020-08-08 20:53:33

标签: unit-testing testing junit mockito powermockito

我试图模拟一个私有方法的输出,该输出在另一个私有方法中被调用,我别无选择,只能测试后面的私有方法,因此我添加了可以在这里表示的示例测试代码,

此示例类

package com.testableClass;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class TestableClass {
    
     private int initialMockMethod(Object obj)
     {
         
         System.out.println(" ++++ Came Here ++++ ");
         
         String str = getRestString("");
         
         System.out.println("str ="+str);
         return str.length();
     }

     private String getRestString(String abc)
     {
         String output="";
         try {

                URL url = new URL("https://gorest.co.in/public-api/users");//your url i.e fetch data from .
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setRequestProperty("Accept", "application/json");
                if (conn.getResponseCode() != 200) {
                    throw new RuntimeException("Failed : HTTP Error code : "
                            + conn.getResponseCode());
                }
                InputStreamReader in = new InputStreamReader(conn.getInputStream());
                BufferedReader br = new BufferedReader(in);
                
                while ((output = br.readLine()) != null) {
                    System.out.println(output);
                }
                conn.disconnect();
                
                return output;

            } catch (Exception e) {
                System.out.println("Exception in NetClientGet:- " + e);
            }
        return abc;
     }
     
}

现在是此PowerMock类

package com.testableClass;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;

import junit.framework.Assert;

@RunWith(PowerMockRunner.class)
@PrepareForTest(fullyQualifiedNames = "com.testableClass.TestableClass")
public class PowerMockTest {
    

    
    @Test
    public void testPrivateMethod() throws Exception
    {
        String message = "Hello PowerMockito";
        String expectation = "Expectation";
 
        TestableClass mock = PowerMockito.spy(new TestableClass());
//      PowerMockito.doReturn(expectation).when(mock, "getRestString", message);
        PowerMockito.when(mock, "getRestString", message).thenReturn(expectation);
        int count = Whitebox.invokeMethod(mock, "initialMockMethod", new Object());
       System.out.println(" +++ Count : "+count+" ++++ ");
        Assert.assertTrue(true);
    }

}

我的问题是当我运行测试用例时

  PowerMockito.when(mock, "getRestString", message).thenReturn(expectation);

执行原始方法并返回原始输出,而我的要求是, 当我的测试用例实际上正在调用私有方法 initialMockMethod 时,不应调用 getRestString ,而应返回我模拟的预期输出,即“ 。 >

1 个答案:

答案 0 :(得分:0)

我会说不要尝试模拟私有方法,而不是使用反射和PowerMock。这是该类的隐藏细节。

我的建议是,如果您的方法发出HTTP请求,则让它执行。但是您可以使用模拟服务器模拟响应。但是要做到这一点,您需要将端点设置为外部,以便可以将其注入。

我稍微改变了你的班级;还是一样的目的。

public class TestableClass {
    private final String resourceUrl;

    public TestableClass(String resourceUrl) {
        this.resourceUrl = resourceUrl;
    }

    public int publicMethod() {
        return initialMockMethod(null);
    }

    private int initialMockMethod(Object obj) {
        var str = getRestString("");
        return str.length();
    }

    private String getRestString(String abc) {
        try {
            var url = new URL(resourceUrl);
            var conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Accept", "application/json");
            if (conn.getResponseCode() != 200) {
                throw new RuntimeException("Failed : HTTP Error code : "
                        + conn.getResponseCode());
            }

            var in = new InputStreamReader(conn.getInputStream());
            var br = new BufferedReader(in);

            var result = br.lines().collect(Collectors.joining("\n"));
            conn.disconnect();

            return result;
        } catch (Exception e) {
            System.out.println("Exception in NetClientGet:- " + e);
        }
        return abc;
    }

}

这是测试

public class TestingTestableClass {

    @Test
    @SneakyThrows
    public void test() {
        final var server = new MockWebServer();
        server.start(9999);

        var instance = new TestableClass("http://127.0.0.1:9999");

        server.enqueue(
                new MockResponse()
                    .setResponseCode(200)
                    .setBody("this is the response")
        );

        final int result = instance.publicMethod();

        Assertions.assertEquals(
                "this is the response".length(),
                result
        );

        final var record = server.takeRequest();
        final var method = record.getMethod();
        Assertions.assertEquals("GET", method);

        server.shutdown();
    }

}

签出MockWebServer here

相关问题