mockhttp icon indicating copy to clipboard operation
mockhttp copied to clipboard

Documentation Request

Open Frankwayne opened this issue 3 years ago • 1 comments

Please add in some documentation on how you can test DelegatingHandlers. I found this Nuget to be very useful in doing so.

public class HandlerToTest: DelegatingHandler
    {
        ILogger<HandlerToTest> _logger;
        public HandlerToTest(ILogger<HandlerToTest> logger)
        {
            _logger = logger;
        }
  protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
             _logger.LogInformation($"Test Me out {response.StatusCode}");
            return response;
        }
    }

To Setup

public class HandlerToTestSpecs
    {
        protected readonly MockHttpMessageHandler httpMock = new MockHttpMessageHandler();
        protected readonly Mock<ILogger<HandlerToTest>> _logger = new Mock<ILogger<HandlerToTest>>();

        protected HttpMessageInvoker MakeSut()
        {
            var subject = new HandlerToTest(_logger.Object);
            subject.InnerHandler = httpMock;
            return new HttpMessageInvoker(subject);
        }
    }

Example Test

public class SendAsyncTests : HandlerToTestSpecs
    {
        [Fact]
        public async Task Should_log()
        {

            var uri = new Uri("http://localhost/test");
            httpMock.Expect(uri.ToString()).Respond("application/json", "{}");

            var invoker = MakeSut();
            HttpRequestMessage message = new HttpRequestMessage();
            message.Method =  HttpMethod.Post;
            message.RequestUri = uri;

            

            await invoker.SendAsync(message,
                new System.Threading.CancellationToken());


            _logger.VerifyMessage(
           LogLevel.Information,
           $"Test Me out {HttpStatusCode.OK}");

        
            httpMock.VerifyNoOutstandingRequest();


        }

Where the extension method for the ILogger is

 public static class MockLoggerExtensions
    {
        public static Mock<ILogger<T>> VerifyMessage<T>(this Mock<ILogger<T>> logger, LogLevel level, string expectedMessage)
        {
            Func<object, Type, bool> state = (v, t) => v.ToString().CompareTo(expectedMessage) == 0;

            logger.Verify(
                x => x.Log(
                    It.Is<LogLevel>(l => l == level),
                    It.IsAny<EventId>(),
                    It.Is<It.IsAnyType>((v, t) => state(v, t)),
                    It.IsAny<Exception>(),
                    It.Is<Func<It.IsAnyType, Exception, string>>((v, t) => true)));

            return logger;
        }
    }

Frankwayne avatar Aug 09 '22 15:08 Frankwayne

I dont mind making a fork and submitting the update to the readme if this is something yall are wiling to have in the documentation

Frankwayne avatar Aug 09 '22 19:08 Frankwayne

@Frankwayne It looks like @richardszalay enabled the Wiki feature - in lieu of a more dedicated docs site, adding something like this as a wiki entry would work (IMO). Assuming @richardszalay is okay with that?

tiesont avatar Jul 27 '23 06:07 tiesont

Thanks @tiesont I have added a simple wiki page for this information

Frankwayne avatar Nov 09 '23 16:11 Frankwayne