2

I'm unit testing a code similar to the one below. There is one use case where I want the GetAsync to throw an exception to be caught in the catch block.

try
{
   var response = await client.GetAsync(url, cancellationToken);
}
catch(Exception e)
{
  _logger.LogError(e)
}

I'm mocking the HttpClient

var factory = new Mock<IHttpClientFactory>();

var httpClient = new HttpClient(handler)
{
   BaseAddress = new Uri("http://localhost:7100")
}

factory.Setup(_ => _.CreateClient(It.IsAny<string>()))
      .Returns(httpClient)
      .Verifiable();

Here I'm mocking the HttpMessageHandler

var handler = new Mock<HttpMessageHandler>();
handler
    .Protected()
    .Setup<Task<HttpResponseMessage>>(
      "SendAsync",
      ItExpr.IsAny<HttpRequestMessage>(),
      ItExpr.IsAny<CancellationToken>()
    )
    .Returns(GetHttpResponseMessage())
    .Verifiable();

GetHttpResponseMessage() is the method where I put the logic to return the appropriate HttpResponseMassage.

HttpResponseMessage GetHttpResponseMessage(int code)
{
   if(code == 200)
   {
      return new HttpResponseMessage{ StatusCode = HttpStatusCode.OK };

   }
   else if(code == 500)
   {
      //StatusCode.InternalServerError   ???
      //throw new Exception() ???
   }
}

None of those 2 above is working. Neither one is causing an exception to be caught by the catch block.

Thanks for helping

1 Answer 1

1

You can setup the async method to throw an exception directly

using Moq;
using Moq.Protected;
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

public class YourTestClass
{
    public void TestMethod()
    {
        var factory = new Mock<IHttpClientFactory>();

        var handler = new Mock<HttpMessageHandler>();
        handler
            .Protected()
            .Setup<Task<HttpResponseMessage>>(
                "SendAsync",
                ItExpr.IsAny<HttpRequestMessage>(),
                ItExpr.IsAny<CancellationToken>()
            )
            .Throws(new HttpRequestException("Simulated exception"))
            .Verifiable();

        var httpClient = new HttpClient(handler.Object)
        {
            BaseAddress = new Uri("http://localhost:7100")
        };

        factory.Setup(_ => _.CreateClient(It.IsAny<string>()))
              .Returns(httpClient)
              .Verifiable();

        
        try
        {
           
        }
        catch (HttpRequestException ex)
        {
         
        }
    }
}

Sign up to request clarification or add additional context in comments.

2 Comments

All the Verifiable calls are pointless in this example since you don't have any Verify calls.
Also, you don't need to set the BaseAddress for this example code...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.