Вы можете использовать Moq
, чтобы издеваться над ним.
Использование Moq для вас
Теперь вы, вероятно, не хотите создавать новый класс для каждого ответа.
Вы могли бы написать вспомогательный класс для тестов, которые вы можете использовать для прайма
какой бы ответ вы ни пожелали, но это, вероятно, не гибкий
достаточно.
Moq - это популярная библиотека .NET, которая помогает имитировать объекты для тестирования.
По сути, он использует отражения и выражения для динамического генерирования
макеты во время выполнения ваших тестов, основанные на спецификациях, которые вы
объявлять с использованием свободного API.
Теперь здесь есть небольшая проблема. Как вы заметили, SendAsync
метод на абстрактном классе HttpMessageHandler защищен.
предостережение: Moq не может автоматически реализовать защищенные методы так просто
с интерфейсами или публичными методами. Причина в том, что бегло API
использует выражения на поддельном типе, и это не может предложить частный или
защищенные члены, так как вы получаете доступ к классу снаружи здесь. Так,
мы должны использовать некоторые более продвинутые функции Moq, чтобы макетировать наши
защищенный метод здесь.
Поэтому у Moq есть API для этого. Вы используете Moq. Защищенный; в вашем
используя пункты, а затем вы можете перейти на свой Moq с
.Protected () метод. Это дает вам несколько дополнительных методов на
Moq, где вы можете получить доступ к защищенным членам, используя их имена.
Полный тест класса с использованием HttpClient с использованием Moq будет выглядеть
как это:
// ARRANGE
var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
handlerMock
.Protected()
// Setup the PROTECTED method to mock
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>()
)
// prepare the expected response of the mocked http call
.ReturnsAsync(new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("[{'id':1,'value':'1'}]"),
})
.Verifiable();
// use real http client with mocked handler here
var httpClient = new HttpClient(handlerMock.Object)
{
BaseAddress = new Uri("http://test.com/"),
};
var subjectUnderTest = new MyTestClass(httpClient);
// ACT
var result = await subjectUnderTest
.GetSomethingRemoteAsync('api/test/whatever');
// ASSERT
result.Should().NotBeNull(); // this is fluent assertions here...
result.Id.Should().Be(1);
// also check the 'http' call was like we expected it
var expectedUri = new Uri("http://test.com/api/test/whatever");
handlerMock.Protected().Verify(
"SendAsync",
Times.Exactly(1), // we expected a single external request
ItExpr.Is<HttpRequestMessage>(req =>
req.Method == HttpMethod.Get // we expected a GET request
&& req.RequestUri == expectedUri // to this uri
),
ItExpr.IsAny<CancellationToken>()
);
Для юнит-тестов вы не издеваетесь над HttpClient. Вместо этого вы издеваетесь
HttpMessageHandler, поместите это в HttpClient и верните его
все, что вы хотите таким образом. Если вы не хотите создавать конкретные
Вывод HttpMessageHandler для каждого теста, вы также можете иметь Moq
создать насмешки для вас автоматически.
Читать всю статью здесь .