gpt4 book ai didi

C# 模拟 IHttpclient & CreateClient

转载 作者:行者123 更新时间:2023-11-30 15:52:32 28 4
gpt4 key购买 nike

我有一个函数想要进行 x 单元测试,但似乎我必须模拟 CreateClient 函数?每当我在测试期间调试它时,var client 似乎等于 null。我正在正确地注入(inject)依赖项,我确信这一点。我想知道的是如何模拟 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 注入(inject)一个模拟对象,您已经为其设置了 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);

更新

为了对 HttpClient 进行单元测试,因为它没有任何接口(interface),您应该按照描述的方式包装它 here .

具体来说我们要安排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/"),
};

现在我们应该在 CreateClient 被调用时返回上面的 httpClient

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

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

关于C# 模拟 IHttpclient & CreateClient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54200046/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com