-1

I am trying to make an PostAsync call using IHttpClientFactory , The cancellation token is working fine and exception is caught by CatchBlock.

But when trying to mock the method the Cancellation token is false and catch block is not caught

Below code for controller and Moq class

ValuesController.cs

[Route("[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        private readonly IHttpClientFactory _httpClientFactory;
        public ValuesController(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }
        [HttpGet]
        public async Task<ActionResult> Get()
        {
            try
            {
                var client = _httpClientFactory.CreateClient("Test");//Statup register this in startup.cs
                 /*services.AddHttpClient("Test", httpClient =>{});*/
                apiTable table = new apiTable();
                table.Name = "Asma Nadeem";
                table.Roll = "6655";
                string json = JsonConvert.SerializeObject(table);
                CancellationTokenSource source = new CancellationTokenSource(1);

                StringContent httpContent = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

                var response = await client.PostAsync("https://jsonplaceholder.typicode.com/posts", httpContent, source.Token);

//Source.Token is false when running the below MOQ test case
                string result = "" + response.Content + " : " + response.StatusCode;

                return StatusCode(200, result);
            }
            catch (OperationCanceledException e)
            {
                return null;
            }
            catch (Exception e)
            {
                return null;
            }
        }
    }

MOQ Class

UnitTest1.cs

public class UnitTest1
    {

        [Fact]
        public void Test1()
        {
            //Arrange
            var mockFactory = new Mock<IHttpClientFactory>();
            var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
            mockHttpMessageHandler.Protected()
                .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
                .ReturnsAsync(new HttpResponseMessage
                {
                    StatusCode = HttpStatusCode.OK,
                    Content = new StringContent("{'name':thecodebuzz,'city':'USA'}"),
                });

            var client = new HttpClient(mockHttpMessageHandler.Object);
            mockFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(client);
            ValuesController controller = new ValuesController(mockFactory.Object);

            //Act
            var result = controller.Get() ;

            //Assert
            Assert.NotNull(result);
            //Assert.Equal(HttpStatusCode.OK, (HttpStatusCode)result.StatusCode);
        }
    }
Rupesh
  • 55
  • 8

1 Answers1

1

If you want to assess the catch branch then setup up your mock to throw an OperationCanceledException

mockHttpMessageHandler.Protected()
                .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
                .ThrowsAsync(new OperationCanceledException(...));
Peter Csala
  • 17,736
  • 16
  • 35
  • 75