gpt4 book ai didi

c# - 以编程方式在本地启动隔离的 Azure 函数(RabbitMQ 触发)以进行集成测试

转载 作者:行者123 更新时间:2023-12-03 06:44:45 24 4
gpt4 key购买 nike

我无法在集成测试中以编程方式本地启动 Azure 函数。

我读到的第一本是:

programmatically-starting-function-app-is-failing-without-descriptive-output

但是没有帮助。

这是我的功能:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using AdmGroup.Omega.Framework.Net.Mail;
using Newtonsoft.Json;

namespace AdmGroup.Omega.Services.Infrastructure.EmailFunction.Functions;

public class EmailService
{
private readonly IMailMessageSender mailMessageSender;

public EmailService(IMailMessageSender mailMessageSender)
{
this.mailMessageSender = mailMessageSender;
}

[Function("EmailService")]
public async Task<IActionResult> Run
(
[RabbitMQTrigger(queueName: "EmailQueue", ConnectionStringSetting = "admgroup:omega:services:infraestructure:emailservice:rabbitmq")] MailMessage email)
{
var strEmail = JsonConvert.SerializeObject(email);
Console.WriteLine(strEmail);
await mailMessageSender.SendAsync(email);

return new OkResult();
}
}

这是 Program.cs(我在其中配置依赖项注入(inject)):

using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using AdmGroup.Omega.Framework.EmailServicing.Services;
using AdmGroup.Omega.Framework.Net.Mail;
using AdmGroup.Omega.Framework.Security;
using Azure.Security.KeyVault.Secrets;
using Microsoft.Extensions.Configuration;
using Azure.Identity;

var config = InitConfiguration();
var clientId = config["AzureKeyVault:ClientId"];
var keyVaultUrl = config["AzureKeyVault:KeyVaultUrl"];

if (!string.IsNullOrEmpty(clientId) && !string.IsNullOrEmpty(keyVaultUrl))
{
var tokenCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = clientId });

var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(s => s.AddSingleton<SecretClient>(_ => new(new Uri(keyVaultUrl), tokenCredential)))
.ConfigureServices(s => s.AddSingleton<AzureKeyVaultSecretManager>())
.ConfigureServices(s => s.AddSingleton<IMailMessageSender, Office365GraphEmailService>())
.Build();

await host.RunAsync();
}

/// <summary>
/// Allow test project to use an appsettings.json file.
/// Read RabbitMQ host and queue name from test appsettings
/// </summary>
/// <returns>Configuration</returns>
static IConfiguration InitConfiguration()
{
return new ConfigurationBuilder()
.AddJsonFile("local.settings.json")
.AddEnvironmentVariables()
.Build();
}

public partial class Program { }

如果我运行

func host start --dotnet-isolated-debug

从 PowerShell(之前安装的“Azure Functions Core Tools”)中,该函数可以正常启动,然后我可以运行测试,但问题是我需要从测试本身启动 func,这就是想法测试自动化。

我可以在测试中注入(inject) AZ 函数类,并暂时删除用于测试的函数参数,我可以使用它来启动它

emailService.Run()

它可以工作,我也可以调试,但问题是当再次启用该参数时,它提示 Run() 中缺少“MailMessage email”参数,这是它将从 RabbitMQ 队列中读取的参数,所以我卡住了...

接下来我可以尝试什么?

编辑 1

我意识到最后很简单,我可以从测试中执行 Program.Main() 并且它应该可以工作,但问题是我得到以下异常:

Exception has occurred: CLR/System.InvalidOperationException
An exception of type 'System.InvalidOperationException' occurred in System.Private.CoreLib.dll but was not handled in user code: 'The gRPC channel URI 'http://:50852' could not be parsed.'

最佳答案

我对此类集成测试的 2 美分。

我通常更喜欢使用最接近生产的设置进行集成测试。对于 Azure Functions,最接近的方法是使用 Docker 容器或部署到 Azure。

最好不要将其作为测试代码的一部分,而是使用使用 ARM 模板部署到 Azure 的脚本或运行构建的 docker 容器(在大多数情况下更容易)来将该部分外部化,并且然后针对它运行测试。

虽然构建自己的主机应该可以工作,因为 Azure Functions 基本上就是这样,但如果您需要使用依赖注入(inject)来测试东西,我充其量会说它对于单元测试来说是可以的,但对于集成测试来说,它与生产还不够接近根据我的喜好。

关于c# - 以编程方式在本地启动隔离的 Azure 函数(RabbitMQ 触发)以进行集成测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74206492/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com