我正在尝试测试API客户端,但出于某种原因,我没有看到我调用的内部方法之一。特别是,似乎永远不会调用AdminClient.MakeHttpCall(基于我在那里设置的断点)。不确定我在这里缺少什么,并且之前使用过Moq。
****编辑****
为了澄清,在GetUserAsync方法中,行var response = await MakeHttpCall(HttpMethod.Get, $"/api/customadmin/user/id/{id}");
,变量response
为null
,并且调试器似乎不会进入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();
}
}