c# - 无法在单元测试中模拟 HttpClient PostAsync()

标签 c# .net unit-testing moq xunit

我正在使用 xUnit 和 Moq 编写测试用例。

我正在尝试模拟 HttpClient 的 PostAsync(),但出现错误。

下面是用于模拟的代码:

   public TestADLS_Operations()
    {
        var mockClient = new Mock<HttpClient>();
        mockClient.Setup(repo => repo.PostAsync(It.IsAny<string>(), It.IsAny<HttpContent>())).Returns(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)));

        this._iADLS_Operations = new ADLS_Operations(mockClient.Object);
    }

错误:

Unsupported expression: repo => repo.PostAsync(It.IsAny(), It.IsAny()) Non-overridable members (here: HttpClient.PostAsync) may not be used in setup / verification expressions.



截图:

enter image description here

最佳答案

Non-overridable members (here: HttpClient.PostAsync) may not be used in setup / verification expressions.


我也试图 mock HttpClient和你一样,我得到了同样的错误信息。

解决方法:
而不是 mock HttpClient , mock HttpMessageHandler .
然后给mockHttpMessageHandler.Object给您的 HttpClient ,然后您将其传递给您的产品代码类。这是有效的,因为 HttpClient用途 HttpMessageHandler引擎盖下:
// Arrange
var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
    .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
    .ReturnsAsync(new HttpResponseMessage { StatusCode = HttpStatusCode.OK });

var client = new HttpClient(mockHttpMessageHandler.Object);
this._iADLS_Operations = new ADLS_Operations(client);
注意:您还需要一个
using Moq.Protected;
在测试文件的顶部。
然后您可以调用使用 PostAsync 的方法来自您的测试,以及 PostAsync将返回 HTTP 状态 OK 响应:
// Act
var returnedItem = this._iADLS_Operations.MethodThatUsesPostAsync(/*parameter(s) here*/);

优势:
mock HttpMessageHandler意味着您的产品代码或测试代码中不需要额外的类。

有用的资源:
  • Unit Testing with the HttpClient
  • How to mock HttpClient in your .NET / C# unit tests
  • 关于c# - 无法在单元测试中模拟 HttpClient PostAsync(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57091410/

    相关文章:

    c# - 如何检查是否已在 Blazor 中设置属性?

    .net - 将光标定位在 Word 文档的开头/结尾

    unit-testing - 了解 "test-first"和 "test-driven"之间的区别

    c# - 如何在全景 View 中的列表框中快速加载数据?

    javascript - 使用@ViewChild {读取: ElementRef } of component causes unit test to fail

    javascript - Jest messageParent 只能在工作人员内部使用

    c# - 将 createprocessasuser 的 stdout 重定向到管道在读取时挂起

    c# - 从内存流复制时显示 Windows 文件复制对话框?

    C# EF 5.0 向 MySQL 数据库添加百万条记录需要数小时

    c# - 如何在 C# 中创建全局变量?