Вам всегда придётся высмеивать зависимости, которые вам нужны.
Одна из проблем здесь заключается в том, что IHttpService
функционирует как сервисный локатор.Ни то, что вы запрашиваете у него, ни его ответ строго напечатаны.Это делает его зависимостью в том, что вы можете технически попросить что-либо или сказать что-нибудь сделать, поэтому я сравниваю это с локатором службы.
Это поможет, если вместо IHttpService
у вас будет строго типизированныйинтерфейс, который делает именно то, что нужно вашему классу.Поскольку у вас есть два запроса, это может быть интерфейс с двумя методами или два совершенно отдельных интерфейса.Вы также можете использовать делегатов.
Вот грубый подход, который может помочь или может вызвать что-то еще.
Сначала абстракция, которая просто говорит о том, что вы хотите сделать.Нет подробностей реализации или упоминания об API отдыха.(Имя, которое я назвал, это хромое. Несколько лет назад я бы назвал его ITicketService
, но это даже более обобщенно.)
public interface ITicketRepository
{
void ChangeAssignedAgent(ITicket ticket, string agentName);
string GetAgentIDFromName(string agentName);
}
Я сделал второй метод частью интерфейса.Вы будете хотеть проверить это отдельно или быть в состоянии смоделировать это отдельно, так, чтобы завершить это.Если вы не хотите, чтобы он был частью того же интерфейса, вы всегда можете создать другой.Мне также нравится использовать несколько делегатов вместо одного интерфейса.Подробнее об этом здесь .
Тогда реализация может быть HttpClient.Я использовал пакет RestSharp NuGet.Я не проверял это (и не могу, так как у меня нет API), поэтому считаю это отправной точкой.Это в значительной степени устраняет необходимость в тестировании того, что вы собираетесь тестировать.
Вы можете сделать это с любой другой клиентской библиотекой HTTP.Я просто использую этот, потому что он знаком, и я знаю, что он обрабатывает создание и удаление клиентов HTTP прямо за кулисами.(Он не создает и не утилизирует их при каждом использовании.)
public class HttpClientTicketRepository : ITicketRepository
{
private readonly string _baseUrl;
public HttpClientTicketRepository(string baseUrl)
{
if(string.IsNullOrEmpty(baseUrl))
throw new ArgumentException($"{nameof(baseUrl)} cannot be null or empty.");
_baseUrl = baseUrl;
}
public void ChangeAssignedAgent(ITicket ticket, string agentName)
{
var agentId = GetAgentIDFromName(agentName);
var client = new RestClient(_baseUrl);
var request = new RestRequest(agentId, dataFormat:DataFormat.Json);
request.AddJsonBody(ticket);
client.Post(request);
}
}
Глядя на то, что вы хотели проверить:
Использует ли он правильный URL-адрес?
Вам не нужно проверять это, потому что URL введен.Это не из этого класса.Он использует любой URL, который вы ему сообщаете.
Это также решает проблему, когда URL будет жестко задан.Вы можете иметь один для dev, один для производства и т. Д., И ввести правильный в зависимости от среды.Поскольку этот класс действует как клиент, ему необходимо знать другие сегменты URL-адреса, но он будет использовать любой базовый URL, который вы ему сообщаете.
Убедитесь, что были использованы соответствующие заголовки, такие как запросбыл в JSON.
Вам не нужно проверять его, потому что он обрабатывается библиотекой.Даже если вы использовали классы .NET Framework, я не думаю, что это то, что вам нужно было бы тестировать, потому что вы тестировали бы фреймворк, а не свой собственный код.Такого рода вещи можно обработать в интеграционном тесте, чтобы убедиться, что все работает непрерывно.
Убедитесь, что был использован запрос POST (у меня есть HttpMessageHandler и использующий делегаты для перехвата и макетаиз Интернета как зависимость в фактическом коде)
Убедитесь, что сериализованное значение JSON не имеет никаких дополнительных свойств, не заполненных.
См. выше.
Теперь любой класснужно обновить тикет, он может зависеть от ITicketRepository
, который действительно легко подделать.
Что касается тестирования HttpClientTicketRepository
, то здесь больше нечего высмеивать.Единственное, что это делает, - это общение с API, использующим HTTP, поэтому вы должны протестировать его с помощью интеграционного теста, нацелив его на фактический экземпляр API и убедившись, что вы получите ожидаемый результат.Этот интеграционный тест охватывает такие вещи, как правильность заголовков и метода HTTP.