Azure functions Azure函数使用静态属性测试函数

Azure functions Azure函数使用静态属性测试函数,azure-functions,Azure Functions,我可以使用Xunit测试Azure函数,如下所示: var req=GenerateReq(); var res=等待MyFunc.Run(请求,记录器); 如果在我的函数中生成一个CosmosDb DocumentClient,如下所示: static DocumentClient docClient=GetCustomClient(); 私有静态文档客户端GetCustomClient() { 字符串cosmosUrl=string.Empty; string cosmosKey=stri

我可以使用Xunit测试Azure函数,如下所示:

var req=GenerateReq();
var res=等待MyFunc.Run(请求,记录器);
如果在我的函数中生成一个CosmosDb DocumentClient,如下所示:

static DocumentClient docClient=GetCustomClient();
私有静态文档客户端GetCustomClient()
{
字符串cosmosUrl=string.Empty;
string cosmosKey=string.Empty;
cosmosUrl=Environment.GetEnvironmentVariable(“cosmosUrl”);
cosmosKey=Environment.GetEnvironmentVariable(“cosmosKey”);
DocumentClient customClient=新DocumentClient(新Uri(cosmosUrl)、cosmosKey、,
新连接策略
{
ConnectionMode=ConnectionMode.Direct,
ConnectionProtocol=Protocol.Tcp,
//自定义受限制请求的重试选项
RetryOptions=新的RetryOptions()
{
MaxRetryAttemptsOnThrottledRequests=10,
MaxRetryWaitTimeInSeconds=30
}
});
返回客户;
}
当我尝试访问docClient时,我遇到一个异常:

The type initializer for 'MyFunc.Get' threw an exception.

有办法解决这个问题吗?

您可以通过使用startup类和设置依赖项注入来解决这个问题。然后,您可以使用IDocumentClient接口注入IDocumentClient接口,而不是生成DocumentClient。从那里,您可以在测试期间模拟IDocumentClient


我写过关于设置启动类的内容,这可能是由错误的静态构造函数或静态属性/字段的错误内联初始化引起的。例如:

类MyFunc
{
静态MyFunc()
{
//这里有错误代码
}

静态DocumentClient docClient=Buggy_GetCustomClient();//您肯定应该使用依赖项注入来解决这个问题。目前,您将在单元测试中使用实际的
DocumentClient
,这是一种糟糕的做法-您应该使用
DocumentClient
mock,这样您就可以控制它的行为

如上所述,创建Startup.cs文件并注册您的客户端:

使用Microsoft.Azure.Functions.Extensions.DependencyInjection;
使用Microsoft.Extensions.DependencyInjection;
[程序集:函数启动(typeof(MyApp.Startup))]
名称空间MyApp
{
公共类启动:函数启动
{
公共覆盖无效配置(IFunctionsHostBuilder)
{
IDocumentClient=GetCustomClient();
builder.Services.AddSingleton(客户);
}
私有静态文档客户端GetCustomClient()
{
字符串cosmosUrl=Environment.GetEnvironmentVariable(“cosmosUrl”);
字符串cosmosKey=Environment.GetEnvironmentVariable(“cosmosKey”);
DocumentClient customClient=新DocumentClient(新Uri(cosmosUrl)、cosmosKey、新连接策略
{
ConnectionMode=ConnectionMode.Direct,
ConnectionProtocol=Protocol.Tcp,
//自定义受限制请求的重试选项
RetryOptions=新的RetryOptions()
{
MaxRetryAttemptsOnThrottledRequests=10,
MaxRetryWaitTimeInSeconds=30
}
});
返回客户;
}
}
}
然后,您可以在函数中插入
IDocumentClient
,作为输入绑定:

[CosmosDB(“数据库名”、“集合名”)]IDocumentClient documentClient
在单元测试中,您可以使用库(如)模拟
IDocumentClient

private Mock_mockDocumentClient=new Mock();
var req=GenerateReq();
var res=await MyFunc.Run(req,logger,_mockDocumentClient.Object);

我应该能够在GetCustomClient上设置断点吗?调用documentClient时,它会立即抛出异常,并且代码似乎没有运行。无法在静态初始化的字段或静态构造函数中设置断点。一种方法是不进行静态初始化。因此,请更改为
静态DocumentCli然后在MyFunc.Run()方法调用中:
docClient=GetCustomClient()
这应该允许命中断点。最初是环境变量导致了问题。我在Azure中有它们,但在local.settings.json中也有它们,但是XUnit没有拾取local.settings.json文件,这真的很烦人吗?因此,这个答案给出了将键从Git Hub上移除并设置Envi的答案rmoment变量。感谢您的帮助,请回答!我建议不要按照您的建议盲目使用DI