Search code examples
c#httpmoqdotnet-httpclientidentitymodel

Using Moq to test HttpClient RequestClientCredentialsTokenAsync


I am trying to mock an Http Client that uses the IdentityModel extension to request a client credentials token.

var tokenResponse = await _httpClient.RequestClientCredentialsTokenAsync(requestContent);

I started doing the setup with:

var httpClient = new Mock<HttpClient>();


var httpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK)
{
    Content = JsonContent.Create(new
    {
        access_token = "token",
        expires_in = 5000
    })
};

var tokenResponse = ProtocolResponse.FromHttpResponseAsync<TokenResponse>(httpResponseMessage);

httpClient.Setup(x => x.RequestClientCredentialsTokenAsync(It.IsAny<ClientCredentialsTokenRequest>(), It.IsAny<CancellationToken>())).Returns(tokenResponse);

But i end up with:

System.NotSupportedException : Unsupported expression: x => x.RequestClientCredentialsTokenAsync(It.IsAny(), It.IsAny()) Extension methods (here: HttpClientTokenRequestExtensions.RequestClientCredentialsTokenAsync) may not be used in setup / verification expressions.

How can i mock the RequestClientCredentialsTokenAsync extension?


Solution

  • Looking at the internals of RequestClientCredentialsTokenAsync we can see that the base request it is using is SendAsync, so we need to mock SendAsync.

    Extension call:

    response = await client.SendAsync(request, cancellationToken).ConfigureAwait();
    

    Final Setup:

    var httpClient = new Mock<HttpClient>();
    
    var httpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK)
    {
        Content = JsonContent.Create(new
        {
            access_token = "token",
            expires_in = 5000
        })
    };
    
    httpClient.Setup(x => x.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(httpResponseMessage));
    

    Result: result