C# 如何对DefaultAzureCredential方法进行单元测试

C# 如何对DefaultAzureCredential方法进行单元测试,c#,azure,unit-testing,azure-managed-identity,defaultazurecredential,C#,Azure,Unit Testing,Azure Managed Identity,Defaultazurecredential,我正在使用默认azure凭据方法获取访问令牌,同时使用功能应用程序的托管标识获取访问令牌。我能够获取令牌。但现在我不确定如何对该方法进行单元测试。这是目前的情况 private async Task RefreshTokenCache() { var tokenCredential = new DefaultAzureCredential(); var accessToken = await tokenCredential.GetTokenAsync( new T

我正在使用默认azure凭据方法获取访问令牌,同时使用功能应用程序的托管标识获取访问令牌。我能够获取令牌。但现在我不确定如何对该方法进行单元测试。这是目前的情况

private async Task RefreshTokenCache()
{
    var tokenCredential = new DefaultAzureCredential();
    var accessToken = await tokenCredential.GetTokenAsync(
        new TokenRequestContext(scopes: new string[] { _config[AppConstants.ADAPIAppId] + "/.default" }) { });
    accessTokenCache.Set(AppConstants.AccessToken, accessToken.Token, DateTimeOffset.Now.AddMinutes(55));
}
是否有类似于httpclientfactory的东西可以插入或传递一些connectionstring,以便我告诉DefaultAzureCredential不要调用Azure

更新


我正在添加更多的上下文。我正在使用它从azure获取我的函数应用程序中的访问令牌,以向APIM进行身份验证。因此,我使用的是HttpMessageHandler,因为我正在检查令牌是否不存在。请调用Azure并获取令牌

在函数应用程序中启动

public override void Configure(IFunctionsHostBuilder builder)
{
 builder.Services.AddHttpClient(AppConstants.ReplyService)
 //Adding token handler middleware to add authentication related details.
 .AddHttpMessageHandler<AccessTokenHandler>();
}
公共覆盖无效配置(IFunctionsHostBuilder)
{
builder.Services.AddHttpClient(AppConstants.ReplyService)
//添加令牌处理程序中间件以添加与身份验证相关的详细信息。
.AddHttpMessageHandler();
}
处理程序文件:

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
 {
 // Use the token to make the call.
 // other details
 request.Headers.Authorization = new AuthenticationHeaderValue(AppConstants.AuthHeader, await GetToken());
  return await base.SendAsync(request, cancellationToken);
 }
 
private async Task<string> GetToken(bool needsRefresh = false)
{
 if (accessTokenCache.GetCount() == 0 || needsRefresh)
 {
  var tokenCredential = new DefaultAzureCredential();
  var accessToken = await tokenCredential.GetTokenAsync(
  new TokenRequestContext(scopes: new string[] { _config["AppId"] + "/.default" }) { });
   accessTokenCache.Set("accessToken", accessToken.Token, DateTimeOffset.Now.AddMinutes(55));
     }
     return accessTokenCache.Get("accessToken")?.ToString() ?? throw new Exception("Unable to Fetch Access Token from Cache");
    }
protectedoverride async Task sendaync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
//使用令牌进行呼叫。
//其他详情
request.Headers.Authorization=新的AuthenticationHeaderValue(AppConstants.AuthHeader,wait GetToken());
返回wait base.sendaync(请求、取消令牌);
}
私有异步任务GetToken(bool needsRefresh=false)
{
if(accessTokenCache.GetCount()==0 | | needsRefresh)
{
var tokenCredential=new DefaultAzureCredential();
var accessToken=wait tokenCredential.GetTokenAsync(
新的TokenRequestContext(作用域:新字符串[]{{u-config[“AppId”]+“/.default”}{});
accessTokenCache.Set(“accessToken”,accessToken.Token,DateTimeOffset.Now.AddMinutes(55));
}
返回accessTokenCache.Get(“accessToken”)?.ToString()??抛出新异常(“无法从缓存中获取访问令牌”);
}

您不应该像这样使用
DefaultAzureCredential
。它需要作为DI层的一部分注入到服务中,例如,这里我正在设置一个新的
BlobServiceClient

私有静态void addAzureClients(IFunctionsHostBuilder)
{
builder.Services.AddAzureClients(builder=>
{
尝试
{
builder.AddBlobServiceClient(Environment.GetEnvironmentVariable(“AzureWebJobsStorage”);
builder.UseCredential(新的DefaultAzureCredential());
}
捕获(例外情况除外)
{
抛出新异常($“加载AddBlobServiceClient:{Environment.GetEnvironmentVariable(“AzureWebJobsStorage”)}时出错),例如;
}
});
}
然后,我使用依赖注入使用客户端:

公共MyClass(BlobServiceClient BlobServiceClient)
{
this.blobServiceClient=blobServiceClient;
}
而且我根本不必碰
DefaultAzureCredential
类。然后,当进行单元测试时,我模拟了
BlobServiceClient
,它是一个抽象类


如果您确实想实际使用
DefaultAzureCredential
,那么您的答案仍然是依赖注入。我建议您这样设置:

在您的启动中:

builder.Services.AddSingleton(()=>newDefaultAzureCredential());
然后(与上面类似)将其注入到您的类中:

public MyClass(令牌凭证令牌凭证)
{
this.tokenCredential=tokenCredential;
}

然后在测试中模拟
TokenCredential
。您不能模拟您
new
创建的类。因此,您现在需要这样做

我正在添加更多上下文。我正在使用它从azure获取我的函数应用程序中的访问令牌,以向APIM进行身份验证。因此,我使用的是HttpMessageHandler,因为我正在检查令牌是否不存在。请调用Azure并获取令牌。我已经用信息更新了这个问题。