2017-06-06 85 views
0

我嘗試測試使用CloseableHttpClient連接的方法。我決定去Mockito並嘲笑所有相關的課程和方法。但是,一旦我開始測試,它就會直接到真正的服務器,而不是被模擬的CloseableHttpClient攔截。Mocked CloseableHttpClient在測試時仍然將連接傳遞給真實服務器

測試

@Test 
    public void testBid() throws IOException { 
     //given: 
     HttpGet httpGet = mock(HttpGet.class); 
     HttpResponse httpResponse = mock(HttpResponse.class); 

     StatusLine statusLine = mock(StatusLine.class); 

     ObserverImp observer = mock(ObserverImp.class); 

     CloseableHttpClient closeableHttpClient = mock(CloseableHttpClient.class); 
     CloseableHttpResponse closeableHttpResponse = mock(CloseableHttpResponse.class); 

     //and: 
     when(statusLine.getStatusCode()).thenReturn(200); 
     when(httpResponse.getStatusLine()).thenReturn(statusLine); 
     when(closeableHttpClient.execute(httpGet)).thenReturn(closeableHttpResponse); 
     when(observer.getKey()).thenReturn("##213"); 


     Buy buy = new Buy(observer); 
     buy.bid(14455); 
    } 

和相關實施

public void buy(double price) { 
     String queryArgs = "command=order&amount=1" + "&price=" + String.valueOf(price); // generates query 

     CloseableHttpClient httpClient = HttpClients.createDefault(); 
     HttpPost post = new HttpPost("wwww.hm.edu/projectGroup1"); 
     post.addHeader("Key", observer.getKey()); 
     try { 
      post.setEntity(new ByteArrayEntity(queryArgs.getBytes("UTF-8"))); 
     } catch (UnsupportedEncodingException e) { 
      System.out.println("Exception in run"); 
     } 
     List<NameValuePair> params = new ArrayList<>(); 

     params.add(new BasicNameValuePair("command", "order")); 
     params.add(new BasicNameValuePair("amount", "1")); 
     params.add(new BasicNameValuePair("price", String.valueOf(price))); 
     try { 
      post.setEntity(new UrlEncodedFormEntity(params)); 
      CloseableHttpResponse response = httpClient.execute(post); 
      HttpEntity entity = response.getEntity(); 
      Scanner in = new Scanner(entity.getContent()); 
      String orderNumber = ""; 
      while (in.hasNext()) { 
       orderNumber = in.nextLine(); 
      } 
      String[] findOrderNumber = orderNumber.split("."); 
      long lastOrderNumber = -1; 
      try { 
       lastOrderNumber = Long.valueOf(findOrderNumber[3]); 
      } catch (NumberFormatException exception) { 
       System.out.println("NumberFormatException"); 
      } finally { 
       if (lastOrderNumber != -1) { 
        observer.setOrderNumber(lastOrderNumber); 
       } 
      } 
      in.close(); 
      EntityUtils.consume(entity); 
      httpClient.close(); 
     } catch (IOException e) { 
      System.out.println("Exception occured during process"); 
     } 
    } 

我想測試我在這裏的教程或類似的問題,但沒有成功發現了幾個代碼段。你能告訴我我在這裏做錯了什麼嗎?

謝謝:)

回答

0

你可以通過構造函數注入CloseableHttpClient httpClient

public class Buy { 
    private ObserverImp observer; 
    private CloseableHttpClient httpClient; 

    public Buy (ObserverImp observer, CloseableHttpClient httpClient) { 
     this.observer = observer; 
     this.httpClient = httpClient; 
    } 

    public void buy(double price) { 
     ... 

     // Comment or remove the line below and use the injected instead... 
     // CloseableHttpClient httpClient = HttpClients.createDefault(); 

     ... 
    } 
} 

而且測試它,如下:

@Test 
public void testBid() throws IOException { 
    //given: 
    HttpGet httpGet = mock(HttpGet.class); 
    HttpResponse httpResponse = mock(HttpResponse.class); 

    StatusLine statusLine = mock(StatusLine.class); 

    ObserverImp observer = mock(ObserverImp.class); 

    CloseableHttpClient closeableHttpClient = mock(CloseableHttpClient.class); 
    CloseableHttpResponse closeableHttpResponse = mock(CloseableHttpResponse.class); 

    //and: 
    when(statusLine.getStatusCode()).thenReturn(200); 
    when(httpResponse.getStatusLine()).thenReturn(statusLine); 
    when(closeableHttpClient.execute(httpGet)).thenReturn(closeableHttpResponse); 
    when(observer.getKey()).thenReturn("##213"); 


    Buy buy = new Buy(observer, closeableHttpClient); 
    buy.bid(14455); 
} 
+0

謝謝你的回答!我應該只是爲了測試而更改CTOR還是一般性改變?或者我可以創建第二個CTOR(重載)好的編碼器走的方式是什麼:)? – AnnaKlein

+0

我剛剛看到我必須對HttpPost執行相同的操作,然後才能正確執行? – AnnaKlein

+0

不客氣。沒有正確的答案。但是你可以重載構造函數,定義只接收'OberserverImp'實例的構造函數,比如'Buy(ObserverImp obs){this(obs,HttpClients.createDefault()); }'。通常,您調用唯一一個參數構造函數。爲了測試,你調用兩個參數構造函數。看到我的觀點? –

0

在你buy方法,你要創建httpClient採用靜態方法,這樣

CloseableHttpClient httpClient = HttpClients.createDefault(); 

現在每次你打電話buy真正 HTTP客戶端被創建,它致電真實服務。相反,你應該通過httpClient的依賴從你的測試代碼模擬httpClient,像

public void buy(double price, HttpClient httpClient) { 
.. 
} 

,並在測試:

public void test() { 

    HttpClient httpClient = mock(HttpClient.class) 
    // mock the behavour 

    // SUT 
    buy(..., httpClient); 

} 
相關問題