我正在从升级我的C#功能应用程序.net 3.1到6.0`.

当我运行测试用例时,我发现,我的测试用例中有1个失败,错误如下.

城堡DynamicProxy.InvalidProxyConstructorArgumentsException:无法实例化类:System的代理.网HttpWebRequest.找不到无参数构造函数.

基本上,我试图模拟HttpWebRequest,下面是我的代码.

var httpWebRequest = new Mock<HttpWebRequest>();

它在室内运行良好.净3.1.我在这两个项目中都使用Moq版本4.16.1.

推荐答案

我花了相当一段时间.NET6最初是为了建立我的单元测试套件而发布的.以下是我如何使用相同的Moq版本4.16.1来实现这一点:

单元测试从基类获得一个Moq HttpClientFactory:

public class UnitTests : BaseUnitTest
{
[Fact]
public async Task Should_Return_GetSomethingAsync()
{
    // Arrange
    IHttpClientFactory httpClientFactory = base.GetHttpClientFactory(new Uri("ExternalWebsiteUrlToMockTheResponse"), new StringContent("A Mock Response JSON Object"));
    YourService yourService = new YourService(httpClientFactory);

    // Act
    Something something = yourService.GetSomethingAsync().Result;

    // Assert
    Assert.IsType<Something>(Something);
    //..
}

在BaseUnitTest.cs类中:

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Moq;
using Moq.Protected;

public class BaseUnitTest
{
public IHttpClientFactory GetHttpClientFactory(Uri uri, StringContent content, HttpStatusCode statusCode = HttpStatusCode.OK)
{
    Mock<HttpMessageHandler> httpMsgHandler = new Mock<HttpMessageHandler>();
    httpMsgHandler.Protected().Setup<Task<HttpResponseMessage>>("SendAsync", new object[2]
    {
        ItExpr.IsAny<HttpRequestMessage>(),
        ItExpr.IsAny<CancellationToken>()
    }).ReturnsAsync(new HttpResponseMessage
    {
        StatusCode = statusCode,
        Content = content
    });
    HttpClient client = new HttpClient(httpMsgHandler.Object);
    client.BaseAddress = uri; 
    Mock<IHttpClientFactory> clientFactory = new Mock<IHttpClientFactory>();
    clientFactory.Setup((IHttpClientFactory cf) => cf.CreateClient(It.IsAny<string>())).Returns(client);

    return clientFactory.Object;
}

您的服务类别或控制器:

public class YourService : IYourService
{
    private readonly IHttpClientFactory _clientFactory;
    private readonly HttpClient _client;
    public YourService(IHttpClientFactory clientFactory)
    {          
        _clientFactory = clientFactory;
        _client = _clientFactory.CreateClient("YourAPI");
    }

    public async Task<Something> GetSomethingAsync()
    {
        using (var request = new HttpRequestMessage(HttpMethod.Post, _client.BaseAddress))
        {
            request.Content = new StringContent($@"{{""jsonrpc"":""2.0"",""method"":""Something"",""params"": [""{SomethingHash}""],""id"":1}}");

            using (var response = await _client.SendAsync(request))
            {
                //System.Diagnostics.Debug.WriteLine(response?.Content.ReadAsStringAsync()?.Result);

                if (response.IsSuccessStatusCode)
                {
                    using (var responseStream = await response.Content.ReadAsStreamAsync())
                    {
                        var options = new JsonSerializerOptions { IncludeFields = true };
                        var something = await JsonSerializer.DeserializeAsync<Something>(responseStream, options);
                        // Check if the transactions from the address we're looking for...
                        if (something != null)
                        {
                            if (something.result?.from == address)
                            {
                                return something;
                            }
                 } } }
                else {
                    string exceptionMsg = $"Message: {response.Content?.ReadAsStringAsync()?.Result}";
                    throw new YourGeneralException(response.StatusCode, exceptionMsg);
                }
            }
        }
        return null;
    }
}

在你的节目里.反恐精英

builder.Services.AddHttpClient("YourAPI", c =>
{
    c.BaseAddress = new Uri("ExternalWebsiteUrlToMockTheResponse");
    c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    c.DefaultRequestHeaders.UserAgent.TryParseAdd("Your Agent");
});

可以展开BaseUnitTest.ccs类也要进行链式测试

.net相关问答推荐

在 F# 中处理 Option - Some(null) 的好策略是什么

WinForm Task.Wait :为什么它会阻塞 UI?

如何确定计时器是否正在运行?

将日期时间转换为日期格式 dd/mm/yyyy

如何获取控制台应用程序的执行目录

每 X 秒执行一次指定函数

MongoDB C# 驱动程序 - 忽略绑定字段

File.ReadAllLines() 和 File.ReadAllText() 有什么区别?

编译错误:显式实现接口时修饰符 'public' 对此项目无效

变量MyException已声明但从未使用

加载程序集、查找类和调用 Run() 方法的正确方法

无法使用 Unity 将依赖项注入 ASP.NET Web API 控制器

一个接口是否应该继承另一个接口

有没有像样的 C# 分析器?

找不到库 hostpolicy.dll

判断对象列表是否包含具有特定值的属性

安装带有恢复操作的 Windows 服务以重新启动

将 SignalR 2.0 .NET 客户端重新连接到服务器集线器的最佳实践

.NET 中的 java.lang.IllegalStateException?

作者主签名的时间戳发现了一个建链问题:UntrustedRoot: self-signed certificate in certificate chain