在 C# 中单元测试 HTTP 请求 [英] Unit testing HTTP requests in c#

查看:45
本文介绍了在 C# 中单元测试 HTTP 请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一些调用 Web 服务、读回响应并对其进行处理的代码.我的代码名义上是这样的:

I'm writing some code that calls a web service, reads back the response and does something with it. My code looks nominally like this:

string body = CreateHttpBody(regularExpression, strategy);

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_url);
request.Method = "POST";
request.ContentType = "text/plain; charset=utf-8";

using (Stream requestStream = request.GetRequestStream())
{
    requestStream.Write(Encoding.UTF8.GetBytes(body), 0, body.Length);
    requestStream.Flush();
}

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
    byte[] data = new byte[response.ContentLength];

    using (Stream stream = response.GetResponseStream())
    {
        int bytesRead = 0;

        while (bytesRead < data.Length)
        {
            bytesRead += stream.Read(data, bytesRead, data.Length - bytesRead);
        }
    }

    return ExtractResponse(Encoding.UTF8.GetString(data));
}

我实际进行任何自定义操作的唯一部分是在 ExtractResponseCreateHttpBody 方法中.然而,仅仅对这些方法进行单元测试感觉是错误的,并希望其余的代码正确地组合在一起.有什么办法可以拦截 HTTP 请求并改为提供模拟数据吗?

The only parts where I am actually doing any custom manipulation is in the ExtractResponse and CreateHttpBody methods. However it feels wrong to just unit test those methods, and hope that the rest of the code comes together correctly. Is there any way I can intercept the HTTP request and feed it mock data instead?

EDIT 此信息现已过时.使用 System.Net.Http.HttpClient 库.

EDIT This information is now out of date. It is much easier to construct this kind of code using the System.Net.Http.HttpClient libraries.

推荐答案

在您的代码中,您无法拦截对 HttpWebRequest 的调用,因为您在同一方法中创建了对象.如果您让另一个对象创建 HttpWebRequest,您可以传入一个模拟对象并使用它进行测试.

In your code you can not intercept the calls to HttpWebRequest because you create the object in the same method. If you let another object create the HttpWebRequest, you can pass in a mock object and use that to test.

所以不是这样:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_url);

使用这个:

IHttpWebRequest request = this.WebRequestFactory.Create(_url);

在您的单元测试中,您可以传入创建模拟对象的 WebRequestFactory.

In your unit test, you can pass in a WebRequestFactory which creates a mock object.

此外,您可以在单独的函数中拆分流读取代码:

Furthermore, you can split of your stream reading code in a separate function:

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
    byte[] data = ReadStream(response.GetResponseStream());
    return ExtractResponse(Encoding.UTF8.GetString(data));
}

这使得单独测试 ReadStream() 成为可能.

This makes it possible to test ReadStream() separately.

要进行更多的集成测试,您可以设置自己的 HTTP 服务器来返回测试数据,并将该服务器的 URL 传递给您的方法.

To do more of an integration test, you can set up your own HTTP server which returns test data, and pass the URL of that server to your method.

这篇关于在 C# 中单元测试 HTTP 请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆