简体   繁体   English

单元测试REST客户端

[英]Unit testing a REST client

I'm fairly new to unit testing but I'm trying to incorporate it into my development process for any new code I write (including bug fixes). 我对单元测试相当新,但我正在尝试将其合并到我编写的任何新代码(包括错误修复)的开发过程中。

I'm working a REST client to communicate with Highrise (37Signals). 我正在使用REST客户端与Highrise(37Signals)进行通信。 How can I unit test this without relying on the external dependency? 如何在不依赖外部依赖的情况下对此进行单元测试? (The REST service). (REST服务)。

For instance I'll have a method called GetPeople() 例如,我将有一个名为GetPeople()的方法

Things I'll want to unit test... 我想要进行单元测试的事情......

  1. The method returns the correct number of people in the account. 该方法返回帐户中正确的人数。
  2. The method returns null if there are no people in the account 如果帐户中没有人,则该方法返回null
  3. The method throws an exception if it can't connect to the service. 如果该方法无法连接到该服务,则会抛出异常。

What do I do to test that the service still functions the same. 我该怎么做才能测试该服务的功能是否相同。 IE person still has a First Name? IE用户还有名字吗? Can I unit test this or is this more of an integration test? 我可以对此进行单元测试,还是更多的集成测试?

For all those who are trying to test actual HttpWebRequest and HttpWebResponse, rather than the mocks. 对于那些试图测试实际的HttpWebRequest和HttpWebResponse而不是模拟的人。 I have mentioned an approach here: http://nripendra-newa.blogspot.com/2012/10/testing-rest-clients.html . 我在这里提到了一种方法: http//nripendra-newa.blogspot.com/2012/10/testing-rest-clients.html I'd call it an integration test rather than unit test though. 我称之为集成测试,而不是单元测试。 Please refer here to see practical implementation: https://github.com/nripendra/Resty.Net/blob/master/tests/Resty.Net.Tests/RestRequestTest.cs 请参阅此处查看实际实施: https//github.com/nripendra/Resty.Net/blob/master/tests/Resty.Net.Tests/RestRequestTest.cs

The approach: 该方法:

  • Use embedded web server. 使用嵌入式Web服务器。 I have used NancyFx, but you can use any eg kayak, cassini etc. 我使用过NancyFx,但你可以使用任何皮艇,卡西尼等。

I assume that your code now uses HttpWebRequest and HttpWebResponse directly. 我假设您的代码现在直接使用HttpWebRequestHttpWebResponse If that's the case, replace all occurrences of HttpWebRequest with IRequest and HttpWebResponse with IResponse . 如果是这种情况,用IRequest替换所有出现的HttpWebRequest和用IResponse替换HttpWebResponse Defined these two interfaces and expose the properties and methods you need, like so: 定义了这两个接口并公开了您需要的属性和方法,如下所示:

public interface IRequest
{
    IResponse GetResponse(string url);
    IResponse GetResponse(string url, object data);
}

public interface IResponse
{
    Stream GetStream();
}

Then it's just to implement these interfaces twice; 然后它只是两次实现这些接口; once for the real application (using HttpWebRequest and HttpWebResponse for doing the HTTP stuff) and once for the tests (not using HTTP, but instead perhaps writing to the console, a log or something similar). 一次用于真正的应用程序(使用HttpWebRequestHttpWebResponse来执行HTTP操作)和一次用于测试(不使用HTTP,而是可能写入控制台,日志或类似的东西)。

Then, when instantiating your client, it's just to inject the implementation of IRequest you want: 然后,在实例化您的客户端时,只需注入您想要的IRequest实现:

var realClient = new Client(new MyHttpRequest());
var testClient = new Client(new MyTestRequest());

It is a very common requirement to unit test code that interacts with external REST APIs. 对与外部REST API交互的单元测试代码来说,这是一个非常常见的要求。 Simulating API servers is actually really annoying to set up usually because most web frameworks require lots of configuration before you can even begin to mock out endpoints. 模拟API服务器实际上通常很烦人,因为大多数Web框架需要大量配置才能开始模拟端点。 For example NancyFX and Asp.net. 例如NancyFX和Asp.net。

In addition to this it can be really hard to assert the data that was sent to the server - essentially meaning you can only check that the response is handled correctly. 除此之外,断言发送到服务器的数据可能非常困难 - 这实际上意味着您只能检查响应是否正确处理。

Even doing integration testing on the real endpoint you can't test what happens when the API you are using goes down or outputs an unusual status code, because you have no control over the endpoint. 即使在真实端点上进行集成测试,也无法测试当您使用的API发生故障时会发生什么情况,或者输出异常状态代码,因为您无法控制端点。

After a long time trying to find a solution to this problem I decided to write a library for mocking out API endpoints using a real web server based on the built in HttpListener class. 经过很长一段时间试图找到这个问题的解决方案后,我决定使用基于内置HttpListener类的真实Web服务器编写一个用于模拟API端点的库。

https://github.com/paulmorrishill/FluentSimulator https://github.com/paulmorrishill/FluentSimulator

This library supports simulating endpoints, headers, responses, slow responses, failed responses. 该库支持模拟端点,标头,响应,响应缓慢,响应失败。 Every type of event that can occur on an HTTP endpoint. HTTP端点上可能发生的每种类型的事件。

It also allows asserting that the data sent to the server was exactly what you expected it to be. 它还允许声明发送到服务器的数据完全符合您的预期。

This is a textbook example for using a mock object . 这是使用模拟对象的教科书示例。 So what you have to do is to implement a fake server simulating the behaviour you are expecting. 所以你要做的就是实现一个模拟你期望的行为的假服务器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM