繁体   English   中英

单元测试Web服务响应

[英]Unit testing Web Service responses

我目前正在C#中为ResellerClub的REST / HTTP API编写API包装器,它在花园种类的JSON对象中提供响应。 通过使用HttpClient类在API端点上执行HTTP POST / GET来执行调用。 JSON.Net用于解析响应。

我如何单独测试API的API包装器功能,因为大多数调用需要一定程度的预期状态才能成功。 例如,我无法测试在我尚未注册的域上创建CNAME记录。

我知道测试不应该依赖于他们没有自己安排的状态,而且我也被告知测试应该永远不会真正处理任何类型的持久性机制,例如数据库。 因此,对于CNAME记录的上述示例,作为测试“安排”阶段的一部分,我应该注册一个测试域,断言它是否有效,然后执行实际的CNAME函数?

另外,我应该想出一些模拟Reseller Club API返回的JSON响应的方法吗?

编辑:我的API类示例(ResellerClubApi.cs)

private async Task<string> DownloadString(string uri) 
{
   // HttpClient object downloads the JSON response string asynchronously
}

我的功能使用DownloadString()方法作为从第三方服务获取响应的通用方法。

public async Task<List<string>> SuggestNames(string domainName) 
{
   // Calls DownloadString() with the correct URI, uses Newtonsoft.JSON to parse 
   // string representation of JSON into object
}

上面的SuggestNames()等方法从更高的服务层调用

public void someServiceLayerMethod() 
{
   var rcApi = new ResellerClubApi();

   var x = rcApi.SuggestNames("something");

   // ...

}

正如您所看到的,当我的ResellerClubApi类是通过HTTP执行操作之前我自己的代码中可能的最低层时,我对如何模拟来自HttpClient的JSON响应感到有些困惑。

我也不知道如何开始使用IoC来处理HttpClient依赖...

谢谢

这是通过使用Moq单元测试模拟HttpMessageHandler来实现的。 http://geekswithblogs.net/abhi/archive/2013/11/20/unit-tests-for-httpclient-using-httpmessagehandler.aspx

我将代码与您的ResellerClubApi类分开,其中包括下载内容和授权,以及涉及连接到远程服务的所有内容,比如ResellerClubClient ,并让它实现一个IResellerClubClient接口。

public interface IResellerClubClient {
    string RequestJson(string url);
}

public class ResellerClubClient : IResellerClubClient {
    // implement your methods here 
}

public ResellerClubApi : IResellerClubApi {
    private readonly IResellerClubClient client;
    // Pass the client as dependency, either manually or using Dependency framework of your choice
    public ResellerClubApi(IResellerClubClient client) {
        this.client = client;
    }

    public List<string> SuggestNames(string domainName) {
        var jsonString = this.client.RequestJson("http://example.com/domains/?name="+domainName);
        // decode it and do something with it
    }
}

这允许您测试ResellerClubApi类,而不依赖于具体的IResellerClubClient实现。 最好的是,您可以更改它(从HttpClient到套接字或其他任何东西,不必触及您的ResellerClubApi

然后在您选择的框架中设置您的单元测试。 Moq框架的一些示例:

var mockedJsonString = '{ succes: true, names: ["domainA.com", "domainA.us"] }';

// create mockup object using IResellerClubClient interface
var resellerClubClient = new Mock<IResellerClubClient>();
// Tell the mock object to return "mockedJsonString" when any parameter is passed to RequestJsonString. 
// If you do more than 1 call in a test, or if that's expected to be called multiple times inside
// the method to be tested, you can setup multiple conditions and results this way too
resellerClubClient.Setup(x => x.RequestJson(It.IsAny<string>())).Returns(mockedJsonString);

var api = new ResellerClubApi(resellerClubClient.Object);
List<string> names = api.SuggestNames("domain.com");

// do your assertions here 

通过将连接和数据检索方法抽象为由接口表示的命中自己的类,您创建了Api类UnitTestable并且易于模拟服务器响应。

当然, ResellerClubClient当然不能进行单元测试。 但它可以在集成测试或验证测试中完成。 UnitTest 永远不应涉及连接到服务器或数据库。

暂无
暂无

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

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