【问题标题】:Simulate no network using Retrofit and MockWebServer使用 Retrofit 和 MockWebServer 模拟无网络
【发布时间】:2014-09-17 02:50:24
【问题描述】:

我想模拟使用RetroFitMockWebServer时的无网络情况。

我目前正在使用Espresso 进行测试,并在开始测试之前将MockWebServers url 提供给RestAdapter。这对于模拟服务器响应等非常有用,但我看不到一种简单的方法来编写当设备没有网络时抛出的java.net.ConnectException 异常。我可以看到 MockResponse 允许限制模拟等,但不是自定义异常。

我知道我可以从根本上模拟 retrofit 使用的实际 Web api 接口,但如果可能的话,我想使用与其他测试相同的方法,使用 MockWebServer

我想我只是错过了一些简单的事情:)

谢谢

【问题讨论】:

    标签: android retrofit mockwebserver


    【解决方案1】:

    Retrofit 有一个 retrofit-mock 模块,它提供了一个 MockRestAdapter 类,其目的是模拟网络延迟和错误。

    这是一个与普通RestAdapter 一起使用来创建服务实例的方法。您可以在 repo 的 samples/mock-github-client/ 文件夹中看到完整示例:https://github.com/square/retrofit/tree/parent-1.9.0/retrofit-samples/mock-github-client

    MockRestAdapter 提供这些 API:

    • setDelay - 设置网络往返延迟,以毫秒为单位。
    • setVariancePercentage - 设置网络往返延迟的正负方差百分比。
    • setErrorPercentage - 设置对calculateIsFailure() 的调用百分比,返回true

    在您的测试中,您可以致电setErrorPercentage(100) 以保证会发生网络错误。默认情况下,抛出错误的时间是延迟的 0 到 3 倍。将延迟设置为 0 以获得即时结果。

    【讨论】:

    【解决方案2】:

    使用 MockWebServer 模拟网络问题的最简单方法是将 SocketPolicy 设置为 SocketPolicy.DISCONNECT_AT_START、SocketPolicy.NO_RESPONSE 等:

    MockWebServer server = new MockWebServer();
    
    MockResponse response = new MockResponse()
      .setSocketPolicy(SocketPolicy.DISCONNECT_AT_START);
    
    server.enqueue(response);
    

    通过这种方式,您可以模拟网络错误,例如连接在响应之前过早关闭或超时异常

    【讨论】:

      【解决方案3】:

      要清楚这里的异常类型,您可以看到不同之处:

      Internet Connection Error

      所以你可以得到两种类型:

      UnknownHostException - 当您没有互联网或未知主机时...为了模拟这种情况,请为适配器设置一个不正确的端点。

      ConnectException - mockwebserver 可以抛出超时异常。您可以在此处查看操作方法:

      https://github.com/square/okhttp/tree/master/mockwebserver

      我真的不知道你的代码是怎样的,但我希望这很有用

      【讨论】:

      • +1 感谢您的回答,但它并没有真正回答问题,因为我想模拟没有网络而不是超时。调度员很有趣。我想知道我是否可以抛出上述异常......
      • 似乎我无法检查网络异常,并且调度程序仅根据其接口抛出 Inturrupted
      【解决方案4】:

      不知道有没有用,不过可以用 MockWebServer 模拟超时:

      String contentType = "Content-type: application/json";
      MockResponse response = MockResponse().setResponseCode(statusCode).setBody(responseBody).addHeader(contentType);
      MockWebServer proxy = new MockWebServer();
      proxy.enqueue(response);
      proxy.setBodyDelayTimeMs(timeoutDelay));
      proxy.play(10000); //Number port - Important!!!
      

      注意:请将您的代码(例如 AsyncHttpClient)的 HttpClient 设置为该端口以进行测试。

      【讨论】:

        【解决方案5】:

        对我有用的是将改造 URL(端点)指向一个随机的不存在的主机。 我使用“thisIsARandomHost.com”和宾果游戏,我能够模拟未知主机异常。

        例如:setAPP_URL = "http://thisIsARandomHost.com/";

        在这里,setAPP_URL 是包含我传递给改造的 url 的字符串变量,当我想在测试中模拟未知主机异常时,我将 url 设置为如上。对于所有其他目的,它被设置为有效的 URL我的应用需要。

        如上述答案所述,MockWebServer 是一个用于模拟改造响应的出色库,但您不需要该库来模拟此异常。对于模拟所有其他异常,我会推荐 MockWebServer ,我在我的项目中经常使用它来测试响应。

        注意:您可以将应用网址设置为任何内容,只要该网址在网络上不存在即可。

        【讨论】:

          【解决方案6】:

          mockWebServer.shutdown() 在执行单元测试之前没问题。

          它在内部关闭套接字连接:

          serverSocket!!.close()
          

          【讨论】:

            猜你喜欢
            • 2017-08-06
            • 1970-01-01
            • 2021-06-15
            • 1970-01-01
            • 2011-01-05
            • 2015-04-27
            • 1970-01-01
            • 1970-01-01
            • 2018-09-22
            相关资源
            最近更新 更多