C# 模拟 IHttpclient 和 CreateClient

2023-12-21

我有一个想要进行 x 单元测试的函数,但似乎我必须模拟 CreateClient 函数?每当我在测试期间调试它时,var client 似乎等于 null。我确信我正在正确注入依赖项。我想知道的是如何模拟 CreateClient。

这是该函数:

    public async Task CreateMessageHistoryAsync(Message message)
    {
        //This seems to be giving a null value
        var client = this.clientFactory.CreateClient(NamedHttpClients.COUCHDB);

        var formatter = new JsonMediaTypeFormatter();
        formatter.SerializerSettings = new JsonSerializerSettings
        {
            Formatting = Formatting.Indented,
            NullValueHandling = NullValueHandling.Ignore,
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };

        Guid id = Guid.NewGuid();            

        var response = await client.PutAsync(id.ToString(), message, formatter);

        if (!response.IsSuccessStatusCode)
        {
            throw new HttpRequestException(await response.Content.ReadAsStringAsync());
        }
    }

这是单元测试,我在一个单独的类中模拟 IHttpClient 并且我正在使用该类。

    [Collection("MockStateCollection")]
    public class CreateMessageHistory
    {
        private readonly MockStateFixture mockStateFixture;

        public CreateMessageHistory(MockStateFixture mockStateFixture)
        {
            this.mockStateFixture = mockStateFixture;
        }

        [Fact]
        public async Task Should_NotThrowHttpRequestException_When_AMessageHistoryIsCreated()
        {
            var recipients = MockMessage.GetRecipients("Acc", "Site 1", "Site 2", "Site 3");
            var message = MockMessage.GetMessage(recipients);

            mockStateFixture
                .MockMessageHistoryService
                .Setup(service => service.CreateMessageHistoryAsync(message));

            var messageHistoryService = new MessageHistoryService(
                mockStateFixture.MockIHttpClientFactory.Object);

            mockStateFixture.MockIHttpClientFactory.Object.CreateClient("CouchDB");

            var task = messageHistoryService.CreateMessageHistoryAsync(message);
            var type = task.GetType();
            Assert.True(type.GetGenericArguments()[0].Name == "VoidTaskResult");
            Assert.True(type.BaseType == typeof(Task));
            await task;

            //await Assert.IsType<Task>(messageHistoryService.CreateMessageHistoryAsync(message));
            // await Assert.ThrowsAsync<HttpRequestException>(() => messageHistoryService.CreateMessageHistoryAsync(message));
        }
    }

在我看来,我还需要模拟 CreateClient 类,是吗?


你应该注入一个模拟对象ClientFactory您已为其设置了CreateClient方法。

// create the mock client
var httpClient = new Mock<IHttpClient>();

// setup method call for client
httpClient.Setup(x=>x.PutAsync(It.IsAny<string>()
                               , It.IsAny<Message>(),
                               , It.IsAny< JsonMediaTypeFormatter>())
          .Returns(Task.FromResult(new HttpResponseMessage { StatusCode = StatusCode.OK}));

// create the mock client factory mock
var httpClientFactoryMock = new Mock<IHttpClientFactory>();

// setup the method call
httpClientFactoryMock.Setup(x=>x.CreateClient(NamedHttpClients.COUCHDB))
                     .Returns(httpClient);

然后你必须通过httpClientFactoryMock.Object到构造函数:

var messageHistoryService = new MessageHistoryService(httpClientFactoryMock.Object);

Update

为了进行单元测试HttpClient因为它没有任何接口,所以你应该按照描述的方式包装它here https://gingter.org/2018/07/26/how-to-mock-httpclient-in-your-net-c-unit-tests/.

具体来说,我们必须如下安排http客户端:

// Mock the handler
var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);

handlerMock.Protected()
// Setup the PROTECTED method to mock
           .Setup<Task<HttpResponseMessage>>("PutAsync",
                                             ItExpr.IsAny<String>(),
                                             ItExpr.IsAny<Message>()
                                             ItExpr.IsAny<MediaTypeFormatter>())
// prepare the expected response of the mocked http call
           .ReturnsAsync(new HttpResponseMessage()
           {
               StatusCode = HttpStatusCode.OK
           })
           .Verifiable();

// use real http client with mocked handler here
var httpClient = new HttpClient(handlerMock.Object)
{
    BaseAddress = new Uri("http://test.com/"),
};

现在我们应该返回上面的内容httpClient when CreateClient叫做。

// create the mock client factory mock
var httpClientFactoryMock = new Mock<IHttpClientFactory>();

// setup the method call
httpClientFactoryMock.Setup(x=>x.CreateClient(NamedHttpClients.COUCHDB))
                     .Returns(httpClient);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 模拟 IHttpclient 和 CreateClient 的相关文章

  • 在 HKCR 中创建新密钥有效,但不起作用

    我有以下代码 它返回 成功 但使用两种不同的工具使用搜索字符串 3BDAAC43 E734 11D5 93AF 00105A990292 搜索注册表不会产生任何结果 RegistryKey RK Registry ClassesRoot C
  • 无需编译的 ES6 单元测试

    我无法找到任何 Mocha 或任何其他通过 Gulp 直接在 ES6 代码上运行的单元测试框架的示例 没有 Babel Webpack 等 我找到了一个在浏览器中使用 ES6 代码运行 Mocha 的示例 经过一些修改 但它不是自动化的 有
  • 按扩展名过滤搜索文件返回太多结果

    我正在开发一个 C 控制台应用程序 它必须管理 Windows 操作系统上的文件 我需要获取具有特定扩展名的文件名 列表 我找到了很多解决方案 最建议的是以下一种 HANDLE hFind WIN32 FIND DATA data hFin
  • 前向声明类型和“已声明为类类型的非类类型”

    我对以下代码有问题 template
  • MVC3中设置下拉列表中的所选项目

    我必须为视图中的下拉列表设置所选项目 但它不起作用 View div class editor label Html LabelFor model gt model Gender div div class editor field Htm
  • 未找到 Boost 库,但编译正常

    我正在尝试在 C 中使用 boost 的文件系统 使用时看起来编译没问题 c c Analyse c o Analyse o g W Wall L usr local lib lboost filesystem lboost system
  • 传递 constexpr 对象

    我决定给予新的C 14的定义constexpr旋转并充分利用它 我决定编写一个小的编译时字符串解析器 然而 我正在努力保持我的对象constexpr将其传递给函数时 考虑以下代码 include
  • 如何将 SOLID 原则应用到现有项目中

    我对这个问题的主观性表示歉意 但我有点卡住了 我希望之前处理过这个问题的人能够提供一些指导和建议 我有 现在已经成为 一个用 C 2 0 编写的非常大的 RESTful API 项目 并且我的一些类已经变得巨大 我的主要 API 类就是一个
  • extern 声明和函数定义都在同一文件中

    我只是浏览了一下gcc源文件 在gcc c 我发现了类似的东西 extern int main int char int main int argc char argv 现在我的疑问是extern是告诉编译器特定的函数不在这个文件中 但可以
  • 如何将 .txt 文件中的数据转换为 xml? C#

    我在一个文本文件中有数千行数据 我想通过将其转换为更容易搜索的内容来轻松搜索 我希望 XML 或其他类型的大型数据结构 尽管我不确定它是否是最好的对于我的想法 每行的数据如下所示 第 31 册 托马斯 乔治 32 34 154 每本书都不是
  • 如何在 C# Designer.cs 代码中使用常量字符串?

    如何在 designer cs 文件中引用常量字符串 一个直接的答案是在我的 cs 文件中创建一个私有字符串变量 然后编辑 Designer cs 文件以使用此变量 而不是对字符串进行硬编码 但设计者不喜欢这样抛出错误 我明白为什么这行不通
  • 不同 C++ 文件中的相同类名

    如果两个 C 文件具有相同名称的类的不同定义 那么当它们被编译和链接时 即使没有警告也会抛出一些东西 例如 a cc class Student public std string foo return A void foo a Stude
  • 在 VS 中运行时如何查看 C# 控制台程序的输出?

    我刚刚编写了一个名为 helloworld 的聪明程序 它是一个 C NET 4 5 控制台应用程序 在扭曲的嵌套逻辑迷宫深处 使用了 Console WriteLine 当我在命令行运行它时 它会运行并且我会看到输出 我可以执行其他命令并
  • 在 C 中使用枚举而不是 #defines 作为编译时常量是否合理?

    在 C 工作了一段时间后 我将回到 C 开发领域 我已经意识到 在不必要的时候应该避免使用宏 以便让编译器在编译时为您做更多的工作 因此 对于常量值 在 C 中我将使用静态 const 变量或 C 11 枚举类来实现良好的作用域 在 C 中
  • memcpy/memmove 到联合成员,这是否设置“活动”成员?

    重要说明 一些评论者似乎认为我是从工会抄袭的 仔细看memcpy 它从普通旧地址复制uint32 t 它不包含在联合中 另外 我正在复制 通过memcpy 到工会的特定成员 u a16 or u x in a union 不直接到整个联盟本
  • 代码中的.net Access Forms身份验证“超时”值

    我正在向我的应用程序添加注销过期警报 并希望从我的代码访问我的 web config 表单身份验证 超时 值 我有什么办法可以做到这一点吗 我认为您可以从 FormsAuthentication 静态类方法中读取它 这比直接读取 web c
  • C++:二叉树所有节点值的总和

    我正在准备面试 我被一个二叉树问题困住了 我们如何计算二叉树所有节点中存在的值的总和 优雅的递归解决方案 伪代码 def sum node if node NULL return 0 return node gt value sum nod
  • EntityFramework 6.0.0.0 读取数据,但不插入

    我创建了一个基于服务的数据库 folderName gt Add New Item gt Data gt Service based Database文件到 WPF 应用程序中 然后我用过Database First方法并创建了Person
  • 在 System.Type 上使用条件断点时出错

    这是函数 public void Init System Type Type this Type Type BuildFieldAttributes BuildDataColumns FieldAttributes 我在第一行设置了一个断点
  • 当用户更改 Windows 中的语言键盘布局时如何通知?

    I want to show a message to user when the user changes the language keyboard layout of Windows for example from EN to FR

随机推荐

  • ASP.NET URL 重写

    如何在 ASP NET 中重写 URL 我希望用户能够访问 http www website com users smith 代替 http www website com user smith 尝试托管 Fusion URL 重写器和反向
  • 在 iPhone 上解析 HTML [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • python 3中的str到时间对象

    给定一对str代表一个对象ISO 8601 https en wikipedia org wiki ISO 8601时间和时区 time str 09 30 time zone str America New York 如何将这两个字符串解
  • Android Studio 失败 - 不支持不支持的主要次要版本 51.0

    直到昨天 我的 Android Studio 工作正常并帮助我创建应用程序 但今天 它开始给出 Gradle 错误 指出不支持主要次要版本 51 0 并要求我配置 gradle 如果我尝试重新导入项目 我会收到相同的错误 我的java版本是
  • RStudio 中的代码折叠:在代码中创建层次结构

    I m writing R scripts in RStudio and I use the code folding https support rstudio com hc en us articles 200484568 Code F
  • 应用 Thunderbird 的 git 系列补丁的最简单方法是什么

    我有一封邮件 其中包含 N 个附件 格式为 000X xxxx patch 我想将所有补丁应用到我的 master 之上 但我希望将所有提交分开 因为原始作者提交了它们 当然包括提交消息 方法一 打开邮件 点击另存为 xxx eml 然后
  • 在列表中查找项目的最快方法?

    我有一个未排序的字符串列表 我可以将这些项目放入数组 列表 排序列表等中 我需要找到在此列表中查找字符串的最快方法 我是否最好将列表转储到数组中 对其进行排序 然后实现二分搜索 或者框架是否提供了一种方法来做到这一点 Thanks 附 针对
  • swift 3 - 创建具有关系的条目

    我第一次处理核心数据中的关系 我现在有什么 let appdelegate NSApplication shared delegate as AppDelegate let context appdelegate persistentCon
  • 如何使用 CAP_SYS_ADMIN

    有人可以向我解释一下如何在 c 中使用或设置 CAP SYS ADMIN 吗 我需要卸载 USB 驱动器的功能 但不知道如何使用它 以下是使用命令行执行此操作的方法 sudo setcap cap sys admin ep executab
  • Openlayers 导出到 KML 并保留我的地图样式

    我成功地从 Openlayers 编写了 KML 但是 kml 文件中不存在任何样式 颜色 描边等 是否可以生成带有样式的 KML 我在这里发现了类似的问题 https gis stackexchange com questions 170
  • 在电子表格中添加行(基于列表的提要)但它不起作用

    我已使用以下代码在电子表格 基于列表的提要 中添加行 但它不起作用 NSMutableArray array NSMutableArray alloc init GDataEntrySpreadsheetList listEntry GDa
  • 通过标签继承选择最佳可用功能

    假设用户定义了以下函数的一些子集 void f int void g int void h int 你的任务是写一个函数call best int 它调用上面声明的列表中的第一个函数 然后您可以假设它也已定义 你是怎样做的 首先 我们定义一
  • 使用 VBA 选择动态单元格范围并创建图表

    我正在尝试使用 VBA 创建使用动态范围的图表 具体来说 我有一个Excel table如下 根据这些数据 我想创建一个图表 并根据要求更改日期范围 例如 在一种情况下 我需要制作 7 月 1 日至 7 月 6 日的图表 而在另一种情况下
  • WebDriver:添加新元素

    有没有一种方法可以在当前 DOM 中添加 插入元素 首先我要说的是 这是一个非常糟糕的主意 认真思考为什么要这样做 那么 如果你还想动态添加元素 那就再考虑一下吧 WebDriver 旨在模仿用户与页面的交互 用户通常不会随意添加元素 也就
  • flutter intellij 插件:java 语言支持吗?

    在我的设置中 Intellij Flutter 插件不支持 Java 代码 它将 Java 类视为文本文件 有什么方法可以让 Intellij 支持我使用 Android 特定的 Java 代码吗 类型检查 完成建议 导入 重构 这是我的颤
  • 使用 SELECT 结果集通过 MySQL 存储过程运行 UPDATE 查询

    我试图了解 MySQL 存储过程 我想检查用户登录凭据是否有效 如果有效 则更新用户在线状态 DROP PROCEDURE IF EXISTS checkUser DELIMITER CREATE PROCEDURE checkUser I
  • Haskell 中的稀疏数组?

    Haskell 中是否有任何标准或 最常用 的方法来表示多维稀疏数组 不会过多牺牲性能 例如 C 中的 map gt 我用谷歌搜索了一下 发现只有一些旧的学术论文 还有其他人也在问这个问题 Thanks Data Map Int Int M
  • 什么时候在构造函数和析构函数中调用 this-> 是安全的

    到目前为止我还没有找到一个确定的答案 什么时候打电话比较安全this gt 来自对象内部 特别是在构造函数和析构函数内部 而且 当使用公共继承时 在此调用的结果上使用向上和向下转换是否安全 例如 class foo foo a b this
  • BigQuery 嵌套字段:ARRAY 类型的列单元不能在 SELECT DISTINCT 中使用

    我想在 BigQuery 中选择表的唯一行 但收到 以下错误 ARRAY 类型的列单位不能在 SELECT DISTINCT 中使用 我的查询是 SELECT DISTINCT from table 表架构 mode NULLABLE na
  • C# 模拟 IHttpclient 和 CreateClient

    我有一个想要进行 x 单元测试的函数 但似乎我必须模拟 CreateClient 函数 每当我在测试期间调试它时 var client 似乎等于 null 我确信我正在正确注入依赖项 我想知道的是如何模拟 CreateClient 这是该函