Perlimpinpin
Perlimpinpin

Reputation: 104

Mock many httpClient calls in the same method

I'm trying to write a unit test using Moq and xunit. In this test, I have to mock two httpClient calls.

I'm writing unit tests for a dotnetcore API. In my API I have to make 2 HTTP calls to another API in order to get the information I want. - in the first call, I get a jwt token from this API. - in the second call, I made a GetAsync call using the token which I getter in the first call to get the information I need.

I don't know how to do to mock these two different calls. In this code, I can mock only one httpClient call

 var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
            handlerMock
               .Protected()
               // Setup the PROTECTED method to mock
               .Setup<Task<HttpResponseMessage>>(
                  "SendAsync",
                  ItExpr.IsAny<HttpRequestMessage>(),
                  ItExpr.IsAny<CancellationToken>()
               )
               // prepare the expected response of the mocked http call
               .ReturnsAsync(new HttpResponseMessage()
               {
                   StatusCode = HttpStatusCode.BadRequest,
                   Content = new StringContent(JsonConvert.SerializeObject(getEnvelopeInformationsResponse), Encoding.UTF8, "application/json")
               })
               .Verifiable();

Do you know how can I do to get two different calls and get two different HttpResponseMessage?

Upvotes: 4

Views: 1962

Answers (1)

Matthew
Matthew

Reputation: 25783

Don't use It.IsAny and use It.Is instead.

The It.Is method will allow you to specify a predicate to see whether the parameter matches.

In your example:

handlerMock
    .Protected()
    .Setup<Task<HttpResponseMessage>>(
        "SendAsync",
        It.Is<HttpRequestMessage>(x => x.RequestUri.Path == "/myjwtpath"),
        It.IsAny<CancellationToken>())
    .ReturnsAsync(new HttpResponseMessage(...))
    .Verifiable();

handlerMock
    .Protected()
    .Setup<Task<HttpResponseMessage>>(
        "SendAsync",
        It.Is<HttpRequestMessage>(x => x.RequestUri.Path == "/myotherpath"),
        It.IsAny<CancellationToken>())
    .ReturnsAsync(new HttpResponseMessage(...))
    .Verifiable();

This will allow you to define a mock that returns two different values depending upon the inputted HttpRequestMethod.RequestUri.Path property.

Upvotes: 7

Related Questions