Sunday 18 February 2018

Mock HttpClient Using HttpMessageHandler in Moq

In this Post we are going to see how to mock the HttpClient using HttpMessageHandler in Moq. For this first we will create sample console app, which retrieves the data from RestApi call.

namespace TestCaseApp
{
    public class Post
    {
        public int userId { set; get; }

        public int id { set; get; }

        public string title { set; get; }

        public string body { set; get; }
    }

}

Above class is a model class

namespace TestCaseApp
{
    public interface IPostUtility
    {
       Task<Post> GetData();
    }

}


From the below method you may see that we are consuming a rest api using Httpclient

namespace TestCaseApp
{
    public class PostUtility: IPostUtility
    {
        HttpClient _client;

        public PostUtility()
        {

        }

        public PostUtility(HttpClient client)
        {
            _client = client;
        }

        public async Task<Post> GetData()
        {

            using (var client = _client ?? new HttpClient())
            {

                HttpResponseMessage response = await client.GetAsync("https://jsonplaceholder.typicode.com/posts/1");
                response.EnsureSuccessStatusCode();

                using (HttpContent content = response.Content)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();                   
                    var articles = JsonConvert.DeserializeObject<Post>(responseBody);
                    return articles;
                }

            }
        }
    }
}


Main.cs
************
class Program
    {
        static void Main(string[] args)
        {
            IPostUtility post = new PostUtility();

            var _post =  post.GetData();
            _post.Wait();
            var result = _post.Result;
            Console.WriteLine($" Id: {result.id}, body: {result.body}");
            Console.ReadLine();
        }      
    }



output:
***********
Id: 1, body: quia et suscipit



Above main method is the calling part , where we can see the result of Post Data. Now are going to write a moq for this method and mock the HttpClient

To Mock the HttpClient we need to use HttpMessageHandler class, mock this class and pass this is in constructor of HttpClient.


Test Method:
***************

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestCaseApp;
using System.Net.Http;
using Moq;
using Moq.Protected;
using System.Threading.Tasks;
using System.Threading;

namespace TestCaseAppTests
{
    [TestClass]
    public class PostUtilityTests
    {
        private IPostUtility _postUtility;
        private Mock<HttpMessageHandler> _mockHttpMessageHandler;

        [TestInitialize]
        public void Initialize()
        {
            _mockHttpMessageHandler = new Mock<HttpMessageHandler>();
            _postUtility = new PostUtility(new HttpClient(_mockHttpMessageHandler.Object));
        }

        [TestMethod]
        public void GetPostData()
        {
            // Arrange          
            _mockHttpMessageHandler.Protected().Setup<Task<HttpResponseMessage>>("SendAsync",
                ItExpr.IsAny<HttpRequestMessage>(),
                ItExpr.IsAny<CancellationToken>())
                .Returns(Task.FromResult(new HttpResponseMessage() {
                    StatusCode = System.Net.HttpStatusCode.OK,Content =new StringContent(PostString())
                }));

            // Act
            var _result = _postUtility.GetData();
            _result.Wait();
            var data = _result.Result;

            // Assert
            Assert.AreEqual(data.body, "sample");
           
        }

        private string PostString()
        {
            return "{\"userId\": 1,\"id\": 1,\"title\": \"rajTitle\",\n  \"body\": \"sample\"}";
        }
    }
}








From this post you can learn how to mock the HttpClient using the  HttpMessageHandler in Moq