Home > database >  Possible to create a mock HttpRequest in .net?
Possible to create a mock HttpRequest in .net?

Time:06-12

using Sports.Services.Network;
using PlainHttp;
using HttpRequest = PlainHttp.HttpRequest;

namespace Proj
{
    public class HttpBase
    {
        public static IHttpRequest ProxiedRequest(string url)
        {
            IHttpRequest request = new HttpRequest(url)
            {
                Proxy = new Uri(Proxies.getRandomProxyConnection()),
                Timeout = TimeSpan.FromMilliseconds(5000)
            };
            return request;
        }
    }
}

One of many inherited classes -

public class HttpSiteA : HttpBase
    {
        public static async Task<IHttpResponse> Get(string url)
        {
            IHttpRequest request = ProxiedRequest(url);
            return await request.SendAsync();
        }
    }

Then later on..

public static async Task<int> ProcessSchedule(SportLeagueStruct league, ILogger logger)
        {
            IHttpResponse response = await HttpSiteA.Get(string.Format(scheduleUrl, league.fanduelName));
            if (response.Succeeded)
            {
                JObject obj = JObject.Parse(response.Body);
                if (obj?["attachments"]?["events"].Count() > 1)
                {
                    logger.LogWarning("FAILURE");
                }
                return 0;
            }
            return 1;
            
        }
var tasks = new List<Task>();
tasks.Add(SiteA.ProcessSchedule(SportLeagues.MLB, logger));
tasks.Add(SiteB.ProcessSchedule(SportLeagues.MLB, logger));
tasks.Add(SiteC.ProcessSchedule(SportLeagues.MLB, logger));
tasks.Add(SiteD.ProcessSchedule(SportLeagues.MLB, logger));
tasks.Add(SiteE.ProcessSchedule(SportLeagues.MLB, logger));
try
{
    await Task.WhenAll(tasks);
}
catch { }

I have the above function ProxiedRequest. If my request timesout, it throws a timeout exception. However, If my request timesout, instead of timing out, I would like to return a mocked IHttpRequest where everything is empty but has a status code of 401. I would simply put a try/catch around the IHttpRequest request = new HttpRequest(url).. and in the catch, return the mocked request. However, I have not been able to figure out how to create a mocked request. Could anyone help me with that?

The idea is I don't want to have to try/catch a timeout exception later in my code and would rather just process the request as a non-200 status code as the handling when processing the request would be the same and I don't need to deal with an exception.

CodePudding user response:

The question is just wrong, exception is thrown not by request object, but by SendAsync() method. See their snippet from github.

try
{
    IHttpResponse response = await request.SendAsync();
}
catch (HttpRequestException ex)
{
    if (ex is HttpRequestTimeoutException)
    {
        Console.WriteLine("Request timed out");
    }
    else
    {
        Console.WriteLine("Something bad happened: {0}", ex);
        // PlainHttp.HttpRequestException: Failed request: [GET https://yyyy.org/] [No such host is known] ---> System.Net.Http.HttpRequestException: No such host is known ---> System.Net.Sockets.SocketException: No such host is known
        // etc.
    }
}

You need to refactor your base class, move your Get method there and include error handling logic if you don't want to handle errors in each implementation.

public class HttpBase
{
    public IHttpRequest ProxiedRequest(string url)
    {
        var request = new HttpRequest(url)
        {
            Proxy = new Uri(""),
            Timeout = TimeSpan.FromMilliseconds(5000)
        };

        return request;
    }

    public virtual async Task<IHttpResponse> Get(string url)
    {
        IHttpRequest request = ProxiedRequest(url);
        try
        {
            return await request.SendAsync();
        }
        catch
        {
            HttpResponseMessage httpResponseMessage = new HttpResponseMessage()
            {
                StatusCode = (HttpStatusCode)401,
                Content = new StringContent("")
            };

            IHttpResponse mockResponse = new HttpResponse(request as HttpRequest, httpResponseMessage);

            return mockResponse;
        }
    }
}
public class HttpSiteA : HttpBase
{
    // override its implementation if it differs from the base
}
  • Related