0

I have a .NET 7 console application that fetches data from an API.

The console application is simple and uses a "typed client", that I am writing:

services.AddSingleton<IMyTypedClient, MyTypedClient>();
services.AddHttpClient<IMyTypedClient, MyTypedClient>(client =>
    {
        client.BaseAddress = new Uri("http://www.randomnumberapi.com/api/v1.0/");
    })
    .SetHandlerLifetime(TimeSpan.FromMinutes(5))
    .AddPolicyHandler(GetRetryPolicy());

static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
    return HttpPolicyExtensions
        .HandleTransientHttpError()
        .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
        .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
}

Here is the "typed client":

public class MyTypedClient : IMyTypedClient
{
    private readonly HttpClient _httpClient;

    public MyTypedClient(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public void GetRandomNumber()
    {
        var response = _httpClient.GetAsync("/random?min=1&max=10&count=5").Result;
        if (response.StatusCode != HttpStatusCode.OK)
        {
            throw new Exception("Failed to get random number");
        }
    }
}

The above code is inspired by MS documentation.

Question I would like to integration test the "typed client" part of the app that I am writing while developing it, but how do I create integration tests for this typed client that takes a HttpClient?

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
wetfield
  • 105
  • 1
  • 7
  • Please add how the app is receiving input and how it is providing output. – Emond Dec 30 '22 at 18:08
  • @Emond The app is running continuously, ie. it will attempt to fetch a random number every 2 minutes. What I want is just to have integration tests of the "typed client" component of the app. – wetfield Dec 30 '22 at 18:12
  • What does it do with the retrieved results? – Emond Dec 30 '22 at 18:18
  • @Emond Printing the result is ok, later I want to make a request to another API and "import" the result, but I just want to make the typed client first. – wetfield Dec 30 '22 at 18:26
  • 1
    1. Go async all the way. Don't use `.Result`. You are asking for trouble. 2. What is your integration test supposed to test? What precisely? – Fildor Dec 30 '22 at 19:09
  • @Fildor 1. True. 2. The integration test is just supposed to test I get a HTTP 200 and print the result from the API, that's all. – wetfield Dec 30 '22 at 19:26
  • 1
    If the console app does not take input and it does not output anything, a meaningful integration test cannot be done. – Emond Dec 30 '22 at 19:29
  • @Emond Thank you for your answer. I am interested in testing the "typed client" component of the app. Why is that not meaningful to do before the app "outputs" something? – wetfield Dec 30 '22 at 19:33
  • I am trying to understand why you want an integration test and not a unit test, Do you want to test the resiliency policies that you have configured ? – YK1 Dec 31 '22 at 05:20
  • @YK1 Sorry for not being clear, it was just meant as a tool during development. I would mark it explicit, since it is unpredictable if the external service works. Does this make sense? – wetfield Dec 31 '22 at 20:37

1 Answers1

0

I ended up just doing the following helper method in my "test" fixture:

    const string baseUrl = "https://someurl";
    const string accessToken = "token";

    var httpClient = new HttpClient
    {
        BaseAddress = new Uri(baseUrl)
    };


    return new MyTypedClient(httpClient, accessToken);
wetfield
  • 105
  • 1
  • 7