I'm trying to write some unit tests for a HttpClient service, and have run into an issue when trying to mock out parts of the code within my GetAccessToken() function.
The service takes in an IHttpClientFactory. From the reading I've done so far it seems that to mock this properly I must mock the IHttpClientFactory, getting it to return a new HttpClient that relies on a mocked HttpMessageHandler, which I have done like this:
var mockHttpClientFactory = new Mock<IHttpClientFactory>();
var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("{'name':thecodebuzz,'city':'USA'}"),
});
var client = new HttpClient(mockHttpMessageHandler.Object);
mockHttpClientFactory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(client);
_httpClientService = new HttpClientService(mockHttpClientFactory.Object, mockConfig.Object);
This aspect works and I've been able to call CreateClient() which is working fine. However the function I'm trying to test calls my GetAccessToken() function, which in turn makes a call to client.GetDiscoveryAccessToken(). I'm guessing the GetDiscoveryAccessToken() function needs to be mocked, but I'm unsure how to proceed.
I've tried creating a mock of the client with a mocked method and returning this when CreateClient is called like so:
var discoDoc = // Mocked disco doc code;
var client = new Mock<HttpClient>(mockHttpMessageHandler.Object);
client.Setup(x => x.GetDiscoveryDocumentAsync(It.IsAny<string>())).Returns(discoDoc);
mockHttpClientFactory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(client);
_httpClientService = new HttpClientService(mockHttpClientFactory.Object, mockConfig.Object);
Unfortunately I get this error: "Cannot convert from 'Moq.Mock' to 'System.Net.Http.HttpClient'" on the line where I tell the CreateClient function what to return. I'm guessing this is because I need to be returning a real HttpClient rather than a Mocked one.
Any ideas about where I can go from here?