问题 单元测试REST客户端


我对单元测试相当新,但我正在尝试将其合并到我编写的任何新代码(包括错误修复)的开发过程中。

我正在使用REST客户端与Highrise(37Signals)进行通信。如何在不依赖外部依赖的情况下对此进行单元测试? (REST服务)。

例如,我将有一个名为的方法 GetPeople()

我想要进行单元测试的事情......

  1. 该方法返回帐户中正确的人数。
  2. 如果帐户中没有人,则该方法返回null
  3. 如果该方法无法连接到该服务,则会抛出异常。

我该怎么做才能测试该服务的功能是否相同。 I.E人还有名字吗?我可以对此进行单元测试,还是更多的集成测试?


12145
2017-09-09 14:15


起源



答案:


我假设您的代码现在使用 HttpWebRequest 和 HttpWebResponse 直。如果是这种情况,请替换所有出现的情况 HttpWebRequest 同 IRequest 和 HttpWebResponse 同 IResponse。定义了这两个接口并公开了您需要的属性和方法,如下所示:

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

public interface IResponse
{
    Stream GetStream();
}

然后它只是两次实现这些接口;一次用于实际应用(使用 HttpWebRequest 和 HttpWebResponse 用于执行HTTP的东西)和一次用于测试(不使用HTTP,而是写入控制台,日志或类似的东西)。

然后,在实例化您的客户端时,它只是注入实现 IRequest 你要:

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

4
2017-09-09 14:23



什么是 Client ? - Kiquenet
@Kiquenet:代码中的任何类当前都依赖于它 HttpWebRequest 和 HttWebResponse 但相反应该取决于你的习惯 IRequest 和 IResponse 接口。 - Asbjørn Ulsberg


答案:


我假设您的代码现在使用 HttpWebRequest 和 HttpWebResponse 直。如果是这种情况,请替换所有出现的情况 HttpWebRequest 同 IRequest 和 HttpWebResponse 同 IResponse。定义了这两个接口并公开了您需要的属性和方法,如下所示:

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

public interface IResponse
{
    Stream GetStream();
}

然后它只是两次实现这些接口;一次用于实际应用(使用 HttpWebRequest 和 HttpWebResponse 用于执行HTTP的东西)和一次用于测试(不使用HTTP,而是写入控制台,日志或类似的东西)。

然后,在实例化您的客户端时,它只是注入实现 IRequest 你要:

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

4
2017-09-09 14:23



什么是 Client ? - Kiquenet
@Kiquenet:代码中的任何类当前都依赖于它 HttpWebRequest 和 HttWebResponse 但相反应该取决于你的习惯 IRequest 和 IResponse 接口。 - Asbjørn Ulsberg


对于那些试图测试实际的HttpWebRequest和HttpWebResponse而不是模拟的人。我在这里提到了一种方法: http://nripendra-newa.blogspot.com/2012/10/testing-rest-clients.html。我称之为集成测试,而不是单元测试。请参考这里看实际实施: https://github.com/nripendra/Resty.Net/blob/master/tests/Resty.Net.Tests/RestRequestTest.cs

该方法:

  • 使用嵌入式Web服务器。我使用过NancyFx,但你可以使用任何例如皮划艇,卡西尼等

4
2017-10-18 15:47



过时了吗?  Resty.Net 现在有效,2018年? 5年前没有更新...... - Kiquenet
@Kiquenet是的,考虑一下过时的HttpClient现在或多或少地为Rest客户端解决了一天的问题。 Resty.Net 应该工作,但可能缺乏现代休息客户所期望的许多功能。 - Nripendra
用得更好 RestSharp or Flurl ? - Kiquenet


这是使用a的教科书示例 模拟对象。所以你要做的就是实现一个假的服务器来模拟你期望的行为。


1
2017-09-09 14:23





对与外部REST API交互的单元测试代码来说,这是一个非常常见的要求。模拟API服务器实际上通常很烦人,因为大多数Web框架需要大量配置才能开始模拟端点。例如NancyFX和Asp.net。

除此之外,断言发送到服务器的数据真的很难 - 实际上意味着您只能检查响应是否正确处理。

即使在真实端点上进行集成测试,也无法测试当您使用的API发生故障时会发生什么情况,或者输出异常状态代码,因为您无法控制端点。

经过很长一段时间试图找到这个问题的解决方案后,我决定使用基于内置HttpListener类的真实Web服务器编写一个用于模拟API端点的库。

https://github.com/paulmorrishill/FluentSimulator

此库支持模拟端点,标头,响应,响应缓慢,响应失败。 HTTP端点上可能发生的每种类型的事件。

它还允许声明发送到服务器的数据完全符合您的预期。


1
2017-08-09 19:11



虽然此链接可能会回答这个问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面发生更改,则仅链接答案可能会变为无效。 - 来自评论 - CDspace