简体   繁体   English

服务器返回 HTTP 响应代码:400:模拟 HttpURLConnection 时

[英]Server returned HTTP response code: 400 : When mocking HttpURLConnection

I am getting following exception while writing test case for my code.我在为我的代码编写测试用例时遇到以下异常。 I mocked the HttpURLConnection but still while debugging I can see that it takes values of dummy URL that I provide in my test.我嘲笑了 HttpURLConnection 但在调试时我仍然可以看到它采用了我在测试中提供的虚拟 URL 的值。

java.io.IOException: Server returned HTTP response code: 400 for URL: http://dummyURL.com
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1840)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
at tcd.edu.repositoryextractor.PullObject.fetchJSONString(PullObject.java:23)
at tcd.edu.repositoryextractor.PullObjectTest.testPullObjectWithValidString(PullObjectTest.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:71)
at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

Following is the test class以下是测试类

public class PullObjectTest {

@InjectMocks
PullObject pullObject = new PullObject();

@Mock
WrappedUrl mockedURL;

@Mock
HttpURLConnection mockedHttpConnection;

@Mock
BufferedReader mockedReader;

@Mock
InputStream mockedInputStream;

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
}

@Test
public void testPullObjectForNullString() {
    assertNull(pullObject.fetchJSONString(null));
}

@SuppressWarnings("rawtypes")
@Test
public void testPullObjectWithValidString() {
    try {
        Mockito.when(mockedURL.openConnection()).thenReturn(mockedHttpConnection);
        Mockito.when(mockedHttpConnection.getInputStream()).thenReturn(mockedInputStream);

        Mockito.when(mockedReader.readLine()).thenAnswer(new Answer() {
            private int count = 1;

            public Object answer(InvocationOnMock invocation) throws Throwable {
                if (count++ == 1)
                    return "This is String";
                return null;
            }
        });

        assertEquals("This is String", pullObject.fetchJSONString("http://dummyURL.com"));
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

Following is the class I need to test以下是我需要测试的课程

public class PullObject {

public String fetchJSONString(String url) {
    if (url == null)
        return null;

    StringBuffer bufferedResponse = new StringBuffer();
    try {
        WrappedUrl obj = new WrappedUrl(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setRequestMethod("GET");

        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));

        String inputLine;
        bufferedResponse = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            bufferedResponse.append(inputLine);
        }
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return bufferedResponse.toString();
}
}

class WrappedUrl {
URL obj;

WrappedUrl(String url) {
    try {
        obj = new URL(url);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
}

public URLConnection openConnection() {
    URLConnection connection = null;
    try {
        connection = obj.openConnection();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return connection;
}
}

So...I have recreated your setup for most part and have a mock now.所以......我已经重新创建了你的大部分设置,现在有一个模拟。

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

public class PullObject {

    private WrappedUrl wrappedUrl;

    public void setWrappedUrl(WrappedUrl wrappedUrl) {
        this.wrappedUrl = wrappedUrl;
    }

    public String fetchJSONString(String url) {
        if (url == null)
            return null;

        StringBuffer bufferedResponse = new StringBuffer();
        try {
            wrappedUrl.setUrl(url);
            HttpURLConnection con = (HttpURLConnection) wrappedUrl.openConnection();
            con.setRequestMethod("GET");

            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));

            String inputLine;
            bufferedResponse = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                bufferedResponse.append(inputLine);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bufferedResponse.toString();
    }
}

I pulled one of the classes out to it's own file:我将其中一个类拉到它自己的文件中:

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;


class WrappedUrl {
    URL obj;

    WrappedUrl(String url) {
        try {
            obj = new URL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

    public void setUrl(String url) {
        try {
            obj = new URL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

    public URLConnection openConnection() {
        URLConnection connection = null;
        try {
            connection = obj.openConnection();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return connection;
    }
}

And here's my test:这是我的测试:

import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import static junit.framework.TestCase.*;

public class PullObjectTest {

    @InjectMocks
    PullObject pullObject = new PullObject();

    @Mock
    WrappedUrl mockedURL;

    @Mock
    HttpURLConnection mockedHttpConnection;

    @Mock
    BufferedReader mockedReader;

    @Mock
    InputStream mockedInputStream;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        pullObject.setWrappedUrl(mockedURL);
    }

    @Test
    public void testPullObjectForNullString() {
        assertNull(pullObject.fetchJSONString(null));
    }

    @SuppressWarnings("rawtypes")
    @Test
    public void testPullObjectWithValidString() {
        try {
            Mockito.when(mockedURL.openConnection()).thenReturn(mockedHttpConnection);
            Mockito.when(mockedHttpConnection.getInputStream()).thenReturn(mockedInputStream);

            Mockito.when(mockedReader.readLine()).thenAnswer(new Answer() {
                private int count = 1;

                public Object answer(InvocationOnMock invocation) throws Throwable {
                    if (count++ == 1)
                        return "This is String";
                    return null;
                }
            });

            assertEquals("This is String", pullObject.fetchJSONString("http://dummyURL.com"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

I'm running into a new issue now but I'm definitely getting a mock object:我现在遇到了一个新问题,但我肯定得到了一个模拟对象:

java.io.IOException: Underlying input stream returned zero bytes
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:288)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.readLine(BufferedReader.java:324)
    at java.io.BufferedReader.readLine(BufferedReader.java:389)
    at PullObject.fetchJSONString(PullObject.java:28)
    at PullObjectTest.testPullObjectWithValidString(PullObjectTest.java:60)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147

) )

The issue is the architecture...you are grabbing instances of the classes instead of a member variable or an injected instance.问题是架构……您正在获取类的实例,而不是成员变量或注入的实例。 Either way...you need to ensure the mock you create in test gets set in your production code.无论哪种方式......您都需要确保您在测试中创建的模拟在您的生产代码中设置。

Hope this helps.希望这可以帮助。

在此处输入图片说明

UPDATE更新

Updated PullObject:更新的 PullObject:

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

class PullObject {

    private WrappedUrl wrappedUrl;

    private HttpURLConnection connection;

    private BufferedReader bufferedReader;

    PullObject(String url) {
        wrappedUrl = new WrappedUrl(url);
        connection = (HttpURLConnection) wrappedUrl.openConnection();
        try {
            bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    void setWrappedUrl(WrappedUrl wrappedUrl) {
        this.wrappedUrl = wrappedUrl;
    }

    void setConnection(HttpURLConnection connection) {
        this.connection = connection;
    }

    void setBufferedReader(BufferedReader bufferedReader) {
        this.bufferedReader = bufferedReader;
    }

    String fetchJSONString(String url) {
        if (url == null)
            return null;

        StringBuffer bufferedResponse = new StringBuffer();
        try {
            connection.setRequestMethod("GET");
            String inputLine;
            bufferedResponse = new StringBuffer();

            if (bufferedReader != null) {
                while ((inputLine = bufferedReader.readLine()) != null) {
                    bufferedResponse.append(inputLine);
                }
                bufferedReader.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bufferedResponse.toString();
    }
}

Update WrapperURL class:更新 WrapperURL 类:

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;


class WrappedUrl {
    private URL obj;

    WrappedUrl(String url) {
        try {
            obj = new URL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

    URLConnection openConnection() {
        URLConnection connection = null;
        try {
            connection = obj.openConnection();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return connection;
    }
}

Updated test that passes:通过的更新测试:

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import static junit.framework.TestCase.*;

public class PullObjectTest {

    private PullObject pullObject;

    @Mock
    WrappedUrl mockedURL;

    @Mock
    HttpURLConnection mockedHttpConnection;

    @Mock
    BufferedReader mockedReader;

    @Mock
    InputStream mockedInputStream;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        pullObject = new PullObject("http://dummyURL.com");
        pullObject.setWrappedUrl(mockedURL);
        pullObject.setBufferedReader(mockedReader);
        pullObject.setConnection(mockedHttpConnection);
    }

    @Test
    public void testPullObjectForNullString() {
        assertNull(pullObject.fetchJSONString(null));
    }

    @SuppressWarnings("rawtypes")
    @Test
    public void testPullObjectWithValidString() {
        try {
            Mockito.when(mockedURL.openConnection()).thenReturn(mockedHttpConnection);
            Mockito.when(mockedHttpConnection.getInputStream()).thenReturn(mockedInputStream);

            Mockito.when(mockedReader.readLine()).thenAnswer(new Answer() {
                private int count = 1;

                public Object answer(InvocationOnMock invocation) throws Throwable {
                    if (count++ == 1)
                        return "This is String";
                    return null;
                }
            });

            assertEquals("This is String", pullObject.fetchJSONString("http://dummyURL.com"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在此处输入图片说明

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

相关问题 服务器返回URL的HTTP响应代码:400:HttpURLConnection错误 - Server returned HTTP response code: 400 for URL : HttpURLConnection Error 服务器返回的HTTP响应代码:400表示URL HttpURLConnection.getInputStream表示JSON POST数据字符串 - Server returned HTTP response code: 400 for URL HttpURLConnection.getInputStream for JSON POST data string HttpURLConnection错误-java.io.IOException:服务器返回的HTTP响应代码:URL的400 - HttpURLConnection Error - java.io.IOException: Server returned HTTP response code: 400 for URL 服务器返回 HTTP 响应代码:400 用于在 java httpurlconnection 中生成 oauth 令牌 - Server returned HTTP response code: 400 for oauth token generation in java httpurlconnection 服务器返回的HTTP响应代码:Keycloak为400 - Server returned HTTP response code: 400 for Keycloak 服务器返回HTTP响应代码:400为URL: - Server returned HTTP response code: 400 for URL: 服务器返回的HTTP响应代码:400 - Server returned HTTP response code: 400 服务器返回HTTP响应代码:400 facebook - Server returned HTTP response code: 400 facebook 服务器返回 HTTP 响应代码:400 - Server returned HTTP response code: 400 服务器使用 httpurlconnection 发出 http 头请求时响应代码 400 - Server responding with response code 400 when making http head request using httpurlconnection
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM