2014-03-29 207 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. 
    } 
}