【问题标题】:How to modify network connection from Java integration test?如何从 Java 集成测试修改网络连接?
【发布时间】:2012-12-10 07:13:18
【问题描述】:

我编写了一个 Java 类 (MyRestClient),它需要访问第三方 RESTful API 并对从其服务器返回的 HTTP 响应进行一些处理。我现在正在尝试在MyRestClient 和第 3 方 API 之间编写一系列成功的集成测试(使用 JUnit 作为底层 testng 库),以确保此类在各种情况下都能正常运行:

  • 一切都很完美(RESTful API 调用正确,服务器返回有意义的响应)
  • 错误的 API 调用和服务器返回应用层错误代码
  • 返回各种非 200 的 HTTP 代码,包括 403、404 和 500
  • 没有网络连接
  • ...等

该列表中的第 4 项(“无网络连接”)是我目前遇到的问题。我在后台使用Jersey 来执行我的实际REST 调用,但是Jersey 本身只是基于java.net.*。如果可能的话,我想在我的shouldThrowExceptionOnBadNetworkConnection() 测试方法正在执行时“破坏”Jersey/Java 触发网络连接的能力,然后将其重新“打开”,以便下一个测试方法可以正常运行。

我一直在查看Charles Proxy,它似乎可以做到这一点,但是似乎没有用于在运行时管理它的 Java 库。

所以我问:如何为特定的集成测试“关闭”Java 网络?提前致谢。

【问题讨论】:

  • 考虑使用 mockito 等模拟库?
  • 感谢@fge,但请在 Bohemian 的回答下查看我的评论 - 基本上 Mockito(及其类似产品)非常适合模拟/存根依赖项......但我不想模拟/存根这些 API来电!我想实际使用它们,并模拟网络中断。
  • 模拟库可以为你做什么,那么问题出在哪里?
  • 最终模拟库只能模拟 Java 对象。它可以说“嘿,通常这个对象的方法执行ABC,但我希望它执行DEF。” 我不想要这个。我希望所有的 Java 对象(我的对象、Jersey 对象和任何java.net.* 对象)都像平常一样运行。但是当 Jersey/Java 去(在网络层)与这些 3rd 方服务器建立连接时,我不希望他们能够因为(非 Java)操作系统看到网络中断。
  • 就像我提到的,Charles 代理可以做到这一点,但像 Mockito 或 EasyMock 这样的 Java 模拟库不能。 这就是问题所在。

标签: java rest networking junit jersey


【解决方案1】:

通过让 MyRestClient 声明一个返回 URL 的受保护方法并让它使用它来代替私有字段,从而使其可测试。

在您的 JUnit 测试中,您使用一个匿名类来覆盖该方法是否会返回垃圾:

MyRestClient willFail = new MyRestClient() {
    protected String getUrl() {
        return "http://not.a.real.address";
    }
}

还有可以做类似事情的模拟库

【讨论】:

  • 感谢@Bohemian - 但您所说的对于 unit 测试是有效的,其目的是将类与其依赖项隔离开来,并将它们作为独立的测试。我正在谈论 集成 测试,并希望针对实际的 3rd 方 API 主动测试 MyRestClient。在这种情况下,我想模拟网络中断,并确保MyRestClient 适当地处理这种情况。
猜你喜欢
  • 1970-01-01
  • 2019-05-26
  • 2020-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-12
  • 2019-02-02
  • 2022-07-22
相关资源
最近更新 更多