在 C# 中对 HTTP 请求进行单元测试

2024-01-19

我正在编写一些代码来调用 Web 服务、读回响应并对其执行某些操作。我的代码名义上看起来像这样:

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));
}

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

EDIT此信息现已过时。使用以下方法构建此类代码要容易得多System.Net.Http.HttpClient https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.118).aspx图书馆。


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

所以代替这个:

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

用这个:

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

在您的单元测试中,您可以传递WebRequestFactory它创建了一个模拟对象。

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

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

这使得可以测试ReadStream()分别地。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C# 中对 HTTP 请求进行单元测试 的相关文章

  • ClickOnce 应用程序错误:部署和应用程序没有匹配的安全区域

    我在 IE 中使用 FireFox 和 Chrome 的 ClickOnce 应用程序时遇到问题 它工作正常 异常的详细信息是 PLATFORM VERSION INFO Windows 6 1 7600 0 Win32NT Common
  • 复制 std::function 的成本有多高?

    While std function是可移动的 但在某些情况下不可能或不方便 复制它会受到重大处罚吗 它是否可能取决于捕获变量的大小 如果它是使用 lambda 表达式创建的 它依赖于实现吗 std function通常被实现为值语义 小缓
  • 如何在加载.NET WinForm应用程序user.config文件时捕获异常?

    有时 在使用默认配置系统的 NET 2 0 WinForm 桌面应用程序中 user config文件将被损坏并且无法再加载 当配置系统尝试加载它时 它会抛出一个System Xml XmlException 抛开 为什么文件首先被损坏 的
  • 在 C 中匹配二进制模式

    我目前正在开发一个 C 程序 需要解析一些定制的数据结构 幸运的是我知道它们是如何构造的 但是我不确定如何在 C 中实现我的解析器 每个结构的长度都是 32 位 并且每个结构都可以通过其二进制签名来识别 举个例子 有两个我感兴趣的特定结构
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 如何使用 jUnit 将测试用例添加到套件中?

    我有 2 个测试类 都扩展了TestCase 每个类都包含一堆针对我的程序运行的单独测试 如何将这两个类 以及它们拥有的所有测试 作为同一套件的一部分执行 我正在使用 jUnit 4 8 在 jUnit4 中你有这样的东西 RunWith
  • 在 C 中初始化变量

    我知道有时如果你不初始化int 如果打印整数 您将得到一个随机数 但将所有内容初始化为零似乎有点愚蠢 我问这个问题是因为我正在评论我的 C 项目 而且我对缩进非常直接 并且它可以完全编译 90 90 谢谢 Stackoverflow 但我想
  • qdbusxml2cpp 未知类型

    在使用 qdbusxml2cpp 程序将以下 xml 转换为 Qt 类时 我收到此错误 qdbusxml2cpp c ObjectManager a ObjectManager ObjectManager cpp xml object ma
  • 从 Linux 内核模块中调用用户空间函数

    我正在编写一个简单的 Linux 字符设备驱动程序 以通过 I O 端口将数据输出到硬件 我有一个执行浮点运算的函数来计算硬件的正确输出 不幸的是 这意味着我需要将此函数保留在用户空间中 因为 Linux 内核不能很好地处理浮点运算 这是设
  • 标准化 UTF-8 到底是什么?

    The 重症监护室项目 http userguide icu project org transforms normalization 现在也有一个PHP库 http us php net manual en class normalize
  • 如何检测表单的任何控件的变化?

    如何检测 C 中表单的任何控件的更改 由于我在一个表单上有许多控件 并且如果表单中的任何控件值发生更改 我需要禁用按钮 我正在寻找一些内置函数 事件处理程序 属性 并且不想为此创建自定义函数 不 我不知道任何时候都会触发任何事件any控制表
  • 外键与独立关系 - Entity Framework 5 有改进吗?

    我读过了several http www ladislavmrnka com 2011 05 foreign key vs independent associations in ef 4 文章和问题 https stackoverflow
  • CMake 无法确定目标的链接器语言

    首先 我查看了this https stackoverflow com questions 11801186 cmake unable to determine linker language with c发帖并找不到解决我的问题的方法 我
  • 如何设置 log4net 每天将我的文件记录到不同的文件夹中?

    我想将每天的所有日志保存在名为 YYYYMMdd 的文件夹中 log4net 应该根据系统日期时间处理创建新文件夹 我如何设置它 我想将一天中的所有日志保存到 n 个 1MB 的文件中 我不想重写旧文件 但想真正拥有一天中的所有日志 我该如
  • Cmake 链接共享库:包含库中的头文件时“没有这样的文件或目录”

    我正在学习使用 CMake 构建库 构建库的代码结构如下 include Test hpp ITest hpp interface src Test cpp ITest cpp 在 CMakeLists txt 中 我用来构建库的句子是 f
  • 不同类型指针之间的减法[重复]

    这个问题在这里已经有答案了 我试图找到两个变量之间的内存距离 具体来说 我需要找到 char 数组和 int 之间的距离 char data 5 int a 0 printf p n p n data 5 a long int distan
  • 方法优化 - C#

    我开发了一种方法 允许我通过参数传入表 字符串 列数组 字符串 和值数组 对象 然后使用这些参数创建参数化查询 虽然它工作得很好 但代码的长度以及多个 for 循环散发出一种代码味道 特别是我觉得我用来在列和值之间插入逗号的方法可以用不同的
  • 从 Excel 应用程序对象中查找位数(32 位/64 位)?

    是否可以从 Microsoft Office Interop Excel ApplicationClass 确定 Excel 是以 32 位还是 64 位运行 Edit该解决方案应该适用于 Excel 2010 和 Excel 2007 此
  • 我的班级应该订阅自己的公共活动吗?

    我正在使用 C 3 0 遵循标准事件模式我有 public event EventHandler

随机推荐

  • 在C#中是否可以创建一个没有类的对象?

    在许多语言中 您可以在不创建数据类型的情况下创建对象 并向该对象添加属性 例如在 JS 或 AS 中 var myObject myObject myParameter hello world 或者您可以用 C 和 C 创建结构 在 C 中
  • C++11 左值、右值和 std::move()

    我有以下代码 include
  • 如何使用 DOCTYPE XHTML 删除 IE8 中的 3D 边框?

    问题 这就是我所做的 body border 0 正如这里所建议的 从 WebBrowser 控件中删除边框 https stackoverflow com questions 2128259 removing border from we
  • GCC -mthumb 与 -marm

    我正在研究使用 GCC 编译的 ARM C C 代码的性能优化 CPU是Tegra 3 据我所知旗帜 mthumb意味着生成旧的 16 位 Thumb 指令 在不同的测试中 我的性能提高了 10 15 marm反对 mthumb Is mt
  • Erlang Dialyzer 整数范围

    module test export f 0 g 0 spec f gt RESULT when RESULT 0 12 spec g gt RESULT when RESULT 0 13 f gt 100 g gt 100 仅运行透析器
  • 使用 C 代码构建 R 包,缺少 dll

    我正在尝试构建一个 R 包 它通过 Call 调用一些 C 子例程 如果我手动执行 R CMD SHLIB 然后 dyn load dll 文件 所有功能都可以正常工作 现在 我正在使用 R CMD build 来构建包 我将所有 C 代码
  • 使用 pySerial 等待 Arduino 自动重置

    我正在尝试在 Linux 上使用非常简单的代码 为了展示问题 从 Arduino 板上读取行 Python代码 arduino py import serial arduino serial Serial dev ttyACM0 with
  • aws - ec2 - mysql - 实例停止,重新启动 - 其他用户密码已更改

    所以我面临这个问题 因此 每当我停止 MySql 服务器 使用 EC2 免费分层微实例 时 我都会更改我的非 root 用户密码 通过它自己 每次停止并重新启动 MySql EC2 实例时 我都需要重置各自的密码 请看下面的截图 执行图像
  • 使用 @ResponseBody 返回对象时的响应代码 500

    我对 spring Restful 编程相当陌生 要求使用控制器方法作为休息服务 所以我尝试以 JSON 格式返回一个对象 但由于某种原因 我得到的响应代码为 500 没有日志文件中的错误和异常 但如果我的返回类型是字符串而不是对象 它就会
  • 无法启动 SQL Developer 4.0.1

    当我尝试启动时 全新机器 新安装的 SQL Developer x64 无 JRE sqldeveloper exe 它卡在 10 左右 我应该查看哪些日志 如果有 以查找错误 版本信息 SQL开发者4 0 1 JDK 1 7 0 55 W
  • gdb coredump - 调用函数或继续执行

    我寻找过与我类似的问题 但我发现的最接近的是GDB 出现 SegFault 后继续调试 https stackoverflow com q 58374854 1667513 我的目标是从 coredump 调用 GDB 中的函数 我有一个
  • 哈希表大小和键的有效位

    我有一个关于哈希表大小和模块化哈希的问题 我指的哈希算法如下 hash key table size array index 我正在阅读一本算法教科书 其中给出了以下建议 如果表大小不是素数 则可能会出现键的所有位在确定 array ind
  • 如何在 Django RESTful API 和 React 中使用 csrf_token?

    我以前有过以下经验Django 如果加行 csrf token in Django然后模板Django处理以下功能csrf token 但是当我尝试使用开发 API 时Django REST Framework然后我就卡住了 我如何添加和处
  • 给定不同大象的寿命,找出大象生存数量最多的时期

    我遇到一个面试问题 给定不同大象的生命周期 找出大象存活数量最多的时期 例如 Input 5 10 6 15 2 7 输出 6 7 3头大象 我想知道这个问题是否可以与 n 个字符串的最长子字符串问题相关 这样每个字符串代表一个时间段的连续
  • 在 WooCommerce 订单和电子邮件通知中显示自定义字段值

    基于 选择 WooCommerce 交付方式后选择日期和时间 https stackoverflow com questions 54886638 choosing a date and time after choosing the wo
  • REST 和非 RESTful URL 一起不起作用

    我所有尝试获取纯静态配置和至少一个非静态 URL 的工作示例都失败了 我有这个页面作为指南 https cwiki apache org confluence display WW REST Plugin https cwiki apach
  • 错误:ExpressionChangedAfterItHasBeenCheckedError:先前值:“ng-untouched:true”。当前值:'ng-untouched: false'

    我已重现该问题堆栈闪电战 https stackblitz com edit angular iah7up用最少的代码 第1步 点击文字 第 2 步 将焦点放在文本字段上 步骤 3 输入 Enter 并检查控制台是否有此错误 错误 Expr
  • 为什么VS2013在使用不同机器时会发布所有网站文件?

    我有一台家用计算机和一台办公室计算机 用于使用 Visual Studio 2013 发布网站 如果我在同一台计算机上进行更改并重新发布 则只会发布更改 而不是所有文件 但是 当在办公室使用我的克隆机时 即使我获取最新版本 进行一小部分更改
  • Python:“就地”更改值的函数?

    我想实现一个函数 允许其参数的值 就地 重新分配 举个例子 一个将增加参数的函数x并减少参数y 这只是一个简单的例子来说明 动机是X and Y实际上是大型数据框的单个元素 他们的表情笨拙 并且这个操作会经历多次迭代 def incdec
  • 在 C# 中对 HTTP 请求进行单元测试

    我正在编写一些代码来调用 Web 服务 读回响应并对其执行某些操作 我的代码名义上看起来像这样 string body CreateHttpBody regularExpression strategy HttpWebRequest req