使用 MockWebServer 模拟嵌套的改造 api 调用

Posted

技术标签:

【中文标题】使用 MockWebServer 模拟嵌套的改造 api 调用【英文标题】:Mocking nested retrofit api calls using MockWebServer 【发布时间】:2022-01-03 07:30:37 【问题描述】:

我正在使用 okhttp3.mockwebserver 编写一个 junit 测试,用于一个 retrofit2 rest api。

精简后的 api 如下所示:

public interface MyApi
    @POST("/api/get-orders")
    retrofit2.Response<Set<String>> getOrders();

    @POST("/api/cxl-order")
    retrofit2.Response<String> cancelOrder(String ordeId);

然后将 api 注入到另一个类,从而委托调用:

    public class MyExchange
    
     private final MyApi api;
     
     public MyExchange(MyApi api)
          this.api = api;
     
    
     public final Set<String> getOrders()
         Response<Set<String>> resp = api.getOrders();
         //parse the response 
         Set<String> result = parse( resp );
         return result;
     
    
    
     public final boolean cancelOrder( String orderId )
       api.cancelOrder( orderId );
    
       //Nested Call
       Set<String> orders = getOrders();
       return !orders.contains(orderId);
    

我在测试中执行以下操作:

 @Test
  public void cancel_order()
      MockWebServer server = new MockWebServer();
      server.start();

      String orderId ="OrderId_123";
      MyApi mockApi = new Retrofit.Builder().baseUrl("/").build().create(MyApi.class);
      MyExchange exchange = new MyExchange(mockApi);

      server.enqueue( new MockResponse().setResponseCode(HttpURLConnection.HTTP_OK, orderId));
      server.enqueue( new MockResponse().setResponseCode(HttpURLConnection.HTTP_OK, Set.of()));

      exchange.cancelOrder(orderId);
    

因为 cancelOrder() 的实现调用了 api.cancelOrder()api.getOrders(),所以我添加了两个对应的模拟响应。但是,看起来只有第一个模拟响应被返回。对于第二个(getOrders),模拟服务器实际上尝试通过 REST 连接,然后因超时而失败。

关于如何模拟嵌套调用的响应有什么想法吗?

干杯!

【问题讨论】:

【参考方案1】:

我最终使用 Dispatcher 来检查请求的路径。 如果路径以“get-orders”结尾,我会为订单发送模拟响应,否则为取消订单。

Dispatcher dispatcher = (request) -> 
  if( request.getPath().endsWith("get-orders")
     return mock response for orders

  else if( request.getPath().endsWith("cxl-orders")
     return mock response for cancel orders
  


mockServer.setDispatcher(dispatcher);

【讨论】:

以上是关于使用 MockWebServer 模拟嵌套的改造 api 调用的主要内容,如果未能解决你的问题,请参考以下文章

使用 Retrofit 和 MockWebServer 模拟无网络

使用 MockWebServer 时超时?

MockWebServer 响应延迟 - 测试超时

如何使用 MockWebServer 验证 POST 正文的内容?

延迟 MockWebServer 响应

text 安卓中使用MockWebServer测试API