毎回テストを書こうとするたびに忘れてしまうのでメモ。
テスト対象のコードはこんな感じ。
public class ProductClass
{
public ProductClass(IHttpClientFactory httpClientFactory)
{
HttpClientFactory = httpClientFactory;
}
public IHttpClientFactory HttpClientFactory { get; }
public async Task<ResponseObject> Get()
{
using var client = HttpClientFactory.CreateClient("ClientName");
using var request = new HttpRequestMessage(HttpMethod.Get, "/request/path");
var response = await client.SendAsync(request).ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
{
return null;
}
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
return JsonConvert.DeserializeObject<ResponseObject>(json);
}
}
テストコードはこうなる。
ポイントは Moq.Protected
を使って HttpMessageHandler
をモックすること。
[TestFixture]
[TestOf(typeof(ProductClass))]
public class ProductClassTests
{
[Test]
public async Task Get()
{
var responseObject = new ResponseObject
{
SomeProperty = "value"
};
var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.Returns(() =>
{
var response = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(responseObject))
};
return Task.FromResult(response);
});
var baseUrl = "https://test.example.jp";
var httpClient = new HttpClient(mockHttpMessageHandler.Object)
{
BaseAddress = new Uri(baseUrl)
};
var mockHttpClientFactory = new Mock<IHttpClientFactory>();
mockHttpClientFactory.Setup(m => m.CreateClient(It.IsAny<string>())).Returns(httpClient);
var targetClient = new MedicalInstituteClient(mockHttpClientFactory.Object);
var result = await targetClient.Get();
Assert.That(result, Is.Not.Null);
Assert.That(result.SomeProperty, Is.EqualTo("value"));
mockHttpMessageHandler.Protected()
.Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(
request => request.Method == HttpMethod.Get
&& request.RequestUri == new Uri($"{baseUrl}/request/path")),
ItExpr.IsAny<CancellationToken>());
mockHttpClientFactory.Verify(m => m.CreateClient(It.Is<string>(s => s == "ClientName")), Times.Once());
}
}