2014-03-29 256 views

回答

2

經過在網上瀏覽一下,我發現MockWebServer是我一直在尋找的。

用於測試HTTP客戶端的可編寫腳本的Web服務器。這個庫可以很容易地測試您的應用程序在進行HTTP和HTTPS調用時是否正確。它允許您指定要返回的響應,然後驗證請求是否按預期進行。

爲了讓設置只需添加以下到您的的build.gradle文件。

androidTestCompile 'com.google.mockwebserver:mockwebserver:20130706' 

這是一個簡單的例子,從他們的GitHub頁面。

public void test() throws Exception { 
    // Create a MockWebServer. These are lean enough that you can create a new 
    // instance for every unit test. 
    MockWebServer server = new MockWebServer(); 

    // Schedule some responses. 
    server.enqueue(new MockResponse().setBody("hello, world!")); 

    // Start the server. 
    server.play(); 

    // Ask the server for its URL. You'll need this to make HTTP requests. 
    URL baseUrl = server.getUrl("/v1/chat/"); 

    // Exercise your application code, which should make those HTTP requests. 
    // Responses are returned in the same order that they are enqueued. 
    Chat chat = new Chat(baseUrl); 

    chat.loadMore(); 
    assertEquals("hello, world!", chat.messages()); 

    // Shut down the server. Instances cannot be reused. 
    server.shutdown(); 
    } 

希望這會有所幫助。

+0

'20130706'代表什麼? –

2

MockWebServer在AndroidTestCase中不適用於我。例如,ECONNREFUSED錯誤發生得非常隨機(在https://github.com/square/okhttp/issues/1069中描述)。我沒有嘗試Robolectric。

從OkHttp 2.2.0開始,我發現了一種替代方法,它對我很有效:攔截器。我把整個模擬響應放在一個存儲在androidTest/assets/上的json文件中,比如'mock_response.json'。當我實例化一個OkHttp進行測試時,我公開了一個攔截器,我將重寫傳入的響應。基本上,body()會改用'mock_response.json'中的數據流。

public class FooApiTest extends AndroidTestCase { 
    public void testFetchData() throws InterruptedException, IOException { 
     // mock_response.json is placed on 'androidTest/assets/' 
     final InputStream stream = getContext().getAssets().open("mock_response.json"); 

     OkHttpClient httpClient = new OkHttpClient(); 
     httpClient.interceptors().add(new Interceptor() { 
      @Override 
      public Response intercept(Chain chain) throws IOException { 
       return new Response.Builder() 
         .protocol(Protocol.HTTP_2) 
         // This is essential as it makes response.isSuccessful() returning true. 
         .code(200) 
         .request(chain.request()) 
         .body(new ResponseBody() { 
          @Override 
          public MediaType contentType() { 
           return null; 
          } 

          @Override 
          public long contentLength() { 
           // Means we don't know the length beforehand. 
           return -1; 
          } 

          @Override 
          public BufferedSource source() { 
           try { 
            return new Buffer().readFrom(stream); 
           } catch (IOException e) { 
            e.printStackTrace(); 
            return null; 
           } 
          } 
         }) 
         .build(); 
      } 
     }); 

     FooApi api = new FooApi(httpClient); 
     api.fetchData(); 

     // TODO: Let's assert the data here. 
    } 
}