C# 如何对DefaultAzureCredential方法进行单元测试
我正在使用默认azure凭据方法获取访问令牌,同时使用功能应用程序的托管标识获取访问令牌。我能够获取令牌。但现在我不确定如何对该方法进行单元测试。这是目前的情况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
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并获取令牌。我已经用信息更新了这个问题。