C#Mocked(Moq)方法未被调用

时间:2017-10-31 19:44:27

标签: c# moq

我正在尝试测试API客户端,但出于某种原因,我没有看到我调用的内部方法之一。特别是,似乎永远不会调用AdminClient.MakeHttpCall(基于我在那里设置的断点)。不确定我在这里缺少什么,并且之前使用过Moq。

****编辑**** 为了澄清,在GetUserAsync方法中,行var response = await MakeHttpCall(HttpMethod.Get, $"/api/customadmin/user/id/{id}");,变量responsenull,并且调试器似乎不会进入MakeHttpCall方法。

测试方法:

[Fact]
[Trait("Category", "AdminClient")]
public async Task ExpiredToken_OnlyTryToRetrieveAccessTokenOnce()
{
    int numNonRetryCalls = 0;
    int numRetryCalls = 0;
    var config = GetConfig();

    var unauthorizedResponse = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
    var mock = new Mock<AdminClient>(config);

    // Set up initial call that returns unauthorized
    mock.Setup(x => x.MakeHttpCallInternal(AdminClient.HttpMethod.Get, It.IsAny<string>(), null, false))
        .ReturnsAsync(unauthorizedResponse)
        .Callback(() => numNonRetryCalls++);

    // Set up retry call that returns unauthorized
    mock.Setup(x => x.MakeHttpCallInternal(AdminClient.HttpMethod.Get, It.IsAny<string>(), null, true))
        .ReturnsAsync(unauthorizedResponse)
        .Callback(() => numRetryCalls++);

    var result = await mock.Object.GetUserAsync(1);

    Assert.Equal(1, numNonRetryCalls);
    Assert.Equal(1, numRetryCalls);
}

的AdminClient:

public class AdminClient : IAdminClient
{
    public enum HttpMethod
    {
        Get,
        Post,
        Put,
        Delete
    }

    private readonly AppMgmtConfig _config;
    private HttpClient _httpClient;

    public AdminClient(AppMgmtConfig config)
    {
        _config = config;
        InitializeHttpClient().Wait();
    }

    private async Task InitializeHttpClient()
    {
        if (_httpClient == null)
        {
            _httpClient = new HttpClient();
            Uri baseUri;
            Uri.TryCreate(_config.ManagementAPIUrl, UriKind.RelativeOrAbsolute, out baseUri);
            _httpClient.BaseAddress = baseUri ?? throw new ArgumentException("Invalid ManagementAPI URL", "ManagementAPIUrl");
            var accessToken = (await _config.GetAccessToken()).AccessToken;
            var authHeaderValue = new AuthenticationHeaderValue("Bearer", accessToken);
            _httpClient.DefaultRequestHeaders.Authorization = authHeaderValue;
        }
    }

    /// <summary>
    /// Get user using the integer ID.
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<CrudOperationResult<DbUser>> GetUserAsync(int id)
    {
        var response = await MakeHttpCall(HttpMethod.Get, $"/api/customadmin/user/id/{id}");
        string contentString = await GetStringContentFromResponseMessage(response);

        var result = JsonConvert.DeserializeObject<CrudOperationResult<DbUser>>(contentString);
        return result;
    }

    internal virtual async Task<HttpResponseMessage> MakeHttpCall(HttpMethod httpMethod, string url, HttpContent content = null)
    {
        try
        {
            var response = await MakeHttpCallInternal(httpMethod, url, content, false);
            response.EnsureSuccessStatusCode();
            return response;
        }
        catch
        {
            await GetNewAccessToken();
            var response = await MakeHttpCallInternal(httpMethod, url, content, true);
            response.EnsureSuccessStatusCode();
            return response;
        }
    }

    internal virtual async Task<HttpResponseMessage> MakeHttpCallInternal(HttpMethod httpMethod, string url, HttpContent content = null, bool isRetryRequest = false)
    {
        HttpResponseMessage responseMessage = null;

        if (httpMethod == HttpMethod.Get)
        {
            responseMessage = await _httpClient.GetAsync(url);
        }
        else if (httpMethod == HttpMethod.Post)
        {
            responseMessage = await _httpClient.PostAsync(url, content);
        }
        else if (httpMethod == HttpMethod.Delete)
        {
            responseMessage = await _httpClient.DeleteAsync(url);
        }

        return responseMessage;
    }

    internal async Task GetNewAccessToken()
    {
        var accessToken = (await _config.GetAccessToken()).AccessToken;
        if (!String.IsNullOrEmpty(accessToken))
        {
            var authHeaderValue = new AuthenticationHeaderValue("Bearer", accessToken);
            _httpClient.DefaultRequestHeaders.Authorization = authHeaderValue;
        }
    }

    private async Task<string> GetStringContentFromResponseMessage(HttpResponseMessage message)
    {
        return await message.Content.ReadAsStringAsync();
    }
}

0 个答案:

没有答案