2017-02-11 161 views
-1

我在爲我的代碼編寫測試用例時出現以下異常。我嘲笑HttpURLConnection,但仍然在調試時,我可以看到它採用了我在測試中提供的虛擬URL的值。服務器返回的HTTP響應代碼:400:當嘲笑HttpURLConnection

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) 

以下是測試類

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

以下是我需要測試

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; 
} 
} 
+0

好像你實際上得到HttpURLConnection類的真實實例。 HttpURLConnection con =(HttpURLConnection)obj.openConnection();您應該嘗試依賴注入或將其設置爲您在測試中創建的模擬對象。你是否嘗試過一個斷點並驗證它是一個模擬? – isuPatches

+0

我對Mockito有點新鮮。所以當我做Mockito.when(mockedURL.openConnection())。然後返回(mockedHttpConnection);它不會返回HttpURLConnection的模擬實例嗎? –

+0

我應用了斷點,但它不模擬HttpURLConnection,我不知道爲什麼。 –

回答

0

因此類...我已經重新創建您的設置對於大多數部分,有一個模擬現在。

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

我把其中一個類從它自己的文件:

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

這是我的測試:

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

我遇到一個新的問題,但現在我m絕對得到一個模擬對象:

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 

問題是架構...您正在抓取類的實例而不是成員變量或注入的實例。無論哪種方式......您需要確保您在測試中創建的模擬得到了您的生產代碼中的設置。

希望這會有所幫助。

enter image description here

UPDATE

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

更新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; 
    } 
} 

更新測試通過:

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

enter image description here

+0

是的,謝謝...錯誤已被刪除..但現在的問題是,我不能將mockedBufferedReader注入到我的類中,因爲它正在創建新的讀取器並給出上面顯示的異常。 –

+0

@SagarSachdeva請看我的更新...我採取了一些自由,重新設計了一下 – isuPatches

相關問題