有一个现有的服务部署在互联网上的公共RESTful api.
对此api的每个请求都需要一些数据准备,如有效的请求字符串构造,一些加密,一些正文消息格式化等.
我想使用TDD为这项服务编写通用客户端.
我知道它并不像StringCalculator kata,需要一些不同的方法.
我不知道如何开始.我想在不使用真实服务的情况下测试它,因此需要一些假的impl.编写一些假实现,将它部署在localhost并从我的测试中调用它会更好吗?或者也许模拟一个负责发送http请求的类?
我希望我的客户端使用如下:
public class ServiceClientTest { @Test public void testSendStoreRequest() { ServiceClient client = new ServiceClient("app_key","private_key") ClientResponse response = client.sendStoreRequest(StorageType.NORMAL,"string_to_store"); assertEquals("200",response.getStatus()); } }
你能指点我如何开始这个吗?
我应该自下而上并编写所有组件(用于创建请求字符串,用于加密等),然后在ServiceClient中使用它们,或者我应该从ServiceClient测试和实现开始自上而下和模拟?
您问题的理想解决方案似乎就是您开始描述的内容.您应该在项目中创建一个接口,该接口将代表外部服务.
public interface CalculatorService { int add(int a,int b); }
这将是您的测试边界.所有UNIT和ACCEPTANCE测试都应针对CalculatorService的模拟或存根运行.他们会很快.
您可以这样做,因为您定义了该合同(该接口实际意味着什么).
稍后,您将拥有一个实现远程HTTP休息服务的实现:
class RemoteRestCalculator implements CalculatorService { public int add(int a,int b) { // call the remote service in here } }
你需要测试这个合同(边界).因此,您将为RemoteRestCalculator编写集成测试.您还可以使用RemoteRestCalculator运行应用程序来进行几对端到端测试,以测试接线等.
现在,回答你的问题,如何测试RemoteRestCalculator?
>理想情况下,您将在测试环境中部署真正的http rest服务的实例,将其指向测试数据库等.因此,您与拥有该服务的人交谈,他们为您提供* .war文件并部署它本地与测试数据库等.有时他们为你做这个,该服务的“沙盒”部署.然后你编写针对该实例运行的RemoteRestCalculator的测试.
>另一种解决方案与您提到的类似.创建“http休息服务模拟器”.然后在本地部署它.诀窍是您必须复制您在该模拟器中使用的所有功能的实际服务行为.因此,模拟器“添加”方法必须与真实方法相同.这个解决方案有很多强大的优点和缺点.然后编写针对该模拟器运行的RemoteRestCalculator的测试.
>有一种中途解决方案,在业界普遍使用.您只需针对实际服务(或有时是模拟器)的本地测试部署运行所有测试.在这种情况下,当您进行大量测试时,测试套件可能非常慢.不建议. Further reading about making builds go faster.>还有一种常用的解决方案,在大多数情况下不推荐使用.你创建了一个“http rest stub class”,有点像mockito mock,但总是通过http进行讨论.所以通常它会启动一个http服务器,你会在使用它之前填充它.它有许多缺点而不是优点.最大的缺点是服务的行为(外部依赖)分散在应用程序的许多测试中.不建议.