I'd like to unit test the following class.
How can I mock the HttpClient
when it's used as a static readonly
field in a static class?
This question doesn't help as the OP is using an instance field for the HttpClient
.
Here's my class:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace Integration.IdentityProvider
{
public static class IdentityProviderApiCaller
{
private static readonly HttpClient HttpClient;
static IdentityProviderApiCaller()
{
HttpClient = HttpClientFactory.Create();
HttpClient.BaseAddress = new Uri("https://someApi.com");
HttpClient.DefaultRequestHeaders.Add("Accept", "application/json");
}
public static async Task<IList<AddGroupResult>> AddGroups(AddGroup[] addGroupsModel)
{
var content = GetContent(addGroupsModel);
var urlPath = "/groups";
var result = await HttpClient.PutAsync(urlPath, content).ConfigureAwait(false);
return await GetObject<IList<AddGroupResult>>(result).ConfigureAwait(false);
}
private static async Task<T> GetObject<T>(HttpResponseMessage result) where T : class
{
if (result.IsSuccessStatusCode)
{
return await DeserializeObject<T>(result.Content).ConfigureAwait(false);
}
var errorResult = await DeserializeObject<ErrorResult>(result.Content).ConfigureAwait(false);
throw new Exception(errorResult.ExceptionMessage);
}
private static async Task<T> DeserializeObject<T>(HttpContent content) where T : class
{
var jsonContent = await content.ReadAsStringAsync().ConfigureAwait(false);
T obj;
try
{
obj = JsonConvert.DeserializeObject<T>(jsonContent);
}
catch (JsonSerializationException)
{
return await Task.FromResult<T>(null).ConfigureAwait(false);
}
return obj;
}
private static StringContent GetContent<T>(T obj)
{
var payload = JsonConvert.SerializeObject(obj);
var content = new StringContent(payload, Encoding.UTF8, "application/json");
return content;
}
}
public class AddGroup
{
public string Name { get; set; }
public string Description { get; set; }
}
public class AddGroupResult
{
public bool IsSuccessful { get; set; }
}
public class ErrorResult
{
public string ExceptionMessage { get; set; }
}
}