我即将踏上编写java库来包装Web API的旅程,我想在此过程中编写测试,以确保一切都很好.我已经使用JUnit很长一段时间了,并且非常适合使用它和PowerMockito/Mockito这样的工具.然而,我担心如果API关闭或我无法访问它,测试可能会失败,因为我最终计划在CI服务器(travis-ci)上运行它,并希望build-test-deploy过程为尽可能接近自动化.
我已经做了很多谷歌搜索,不幸的是我在这里发现的大部分问题都是关于测试程序员已经编写或可以在本地设置的API.我知道可以通过一点点的修补来复制API的基本功能,尽管这感觉更像是向前退一步而不是前进.
我目前正在脑海中起草创意,到目前为止,这感觉就像是一个中等可靠的解决方案,尽管如果有人能够验证这一点或者提供更好的解决方案,那就太好了.
TestUtil.java
public static boolean isReachable() { try (Socket socket = new Socket("api.host.com", 80)) { return true; } catch (Exception e) { return false; } }
TestCase.java
@BeforeClass public static void testReachable() { Assume.assumeTrue("API was not reachable, test cannot run", TestUtil.isReachable()); }
我@BeforeClass
只是出于偏执而假设它.
但是,这不会解决HTTP错误,只会检查是否有东西在端口80上侦听.是否值得替换HEAD
请求?除了检查错误,我真的不确定.我不愿意使用HTTP而没有确认它是最好的方法,因为这个库有可能变得非常大.
编辑:
我只是偶然发现InetAddress#isReachable()
,虽然根据我正在阅读的一篇文章,它并不是最可靠的.
您应该区分单元测试和集成测试.
单元测试不应该依赖于网络和文件系统等基础设施.所有这些方面都应该重新排除,例如在单元测试期间模拟的单独的类或方法中.我总是把单元测试写成'白盒'测试,我尝试使用代码覆盖工具来覆盖代码中的每个可能的流程.
在您的情况下,您可以为项目中的业务逻辑编写单元测试,例如以哪种顺序调用API调用,逻辑规则取决于API调用的结果,可能是一些与内容相关的验证和错误处理,映射您的域对象到远程API的协议等.
这只留下实际调用API的部分未经测试.为此,我将运行一个嵌入式Web服务器(例如Jetty),它托管一个提供熟响应的远程API的模拟版本.然后,您可以编写调用此本地服务器的集成测试来检查您的网络代码及其配置.
当我使用像Spring-WS或JAXB这样的框架时,我经常跳过集成测试部分,因为这意味着要做很多工作来测试你的配置,没有必要测试这些框架的代码.这可能只是我懒惰但我总是试图权衡创建测试的努力与预期的好处.
当您拥有复杂的服务环境并进行大量的compex映射,配置和路由时,它就变成了另一个故事.然后,您的集成测试是验证所有服务是否已连接并正确相互通信的最佳方法.我将这些称为"黑匣子"测试,您可以根据整个系统的预期功能(例如用户故事)指定测试,而不依赖于实现细节.