我有一个要进行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类吗?
答案 0 :(得分:3)
您应该为已设置了LocalizedControlType, ClassNAme and Name
方法的AutomationId and RuntimeId
注入模拟对象。
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
进行单元测试,因为它没有任何接口,则应按照here所述对其进行包装。
具体来说,我们必须按以下方式安排http客户端:
var messageHistoryService = new MessageHistoryService(httpClientFactoryMock.Object);
现在,当调用HttpClient
时,我们应该返回上面的// 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