.net-core - 配置 MassTransit 以使用 WebApplicationFactory 进行测试
问题描述
我有一个 ASP.NET Core Web 应用程序和测试设置,WebApplicationFactory
用于测试我的控制器操作。我以前使用过 RawRabbit,我很容易模拟IBusClient
并将其作为单例添加到 DI 容器中。在WebApplicationFactory<TStartup>.CreateWebHostBuilder()
我调用这个扩展方法来添加我的模拟IBusClient
实例,就像这样;
/// <summary>
/// Configures the service bus.
/// </summary>
/// <param name="webHostBuilder">The web host builder.</param>
/// <returns>A web host builder.</returns>
public static IWebHostBuilder ConfigureTestServiceBus(this IWebHostBuilder webHostBuilder)
{
webHostBuilder.ConfigureTestServices(services =>
{
services.AddSingleton<IBusClient, MY_MOCK_INSTANCE>
});
return webHostBuilder;
}
但现在 RawRabbit 存在差距,这让我决定搬到 MassTransit。但是,我想知道是否已经有更好的方法可以将它注册IBus
到我的容器中,而无需在我的测试中模拟它。不确定InMemoryTestFixture
,BusTestFixture
或BusTestHarness
是否是我的问题的解决方案。不知道如何一起使用它们以及它们的作用。
顺便说一句,在我的 ASP.NET Core 应用程序中,我有一个可重用的扩展方法设置,如下面的代码,以便在启动时将我连接到 RabbitMQ。
/// <summary>
/// Adds the service bus.
/// </summary>
/// <param name="services">The services.</param>
/// <param name="configurator">The configurator.</param>
/// <returns>A service collection.</returns>
public static IServiceCollection AddServiceBus(this IServiceCollection services, Action<IServiceCollectionConfigurator> configurator)
{
var rabbitMqConfig = new ConfigurationBuilder()
.AddJsonFile("/app/configs/service-bus.json", optional: false, reloadOnChange: true)
.Build();
// Setup DI for MassTransit.
services.AddMassTransit(x =>
{
configurator(x);
// Get the json configuration and use it to setup connection to RabbitMQ.
var rabbitMQConfig = rabbitMqConfig.GetSection(ServiceBusOptionsKey).Get<RabbitMQOptions>();
// Add bus to the container.
x.AddBus(provider => Bus.Factory.CreateUsingRabbitMq(cfg =>
{
cfg.Host(
new Uri(rabbitMQConfig.Host),
hostConfig =>
{
hostConfig.Username(rabbitMQConfig.Username);
hostConfig.Password(rabbitMQConfig.Password);
hostConfig.Heartbeat(rabbitMQConfig.Heartbeat);
});
cfg.ConfigureEndpoints(provider);
// Add Serilog logging.
cfg.UseSerilog();
}));
});
// Add the hosted service that starts and stops the BusControl.
services.AddSingleton<IMessageDataRepository, EncryptedMessageDataRepository>();
services.AddSingleton<IEndpointNameFormatter, EndpointNameFormatter>();
services.AddSingleton<IBus>(provider => provider.GetRequiredService<IBusControl>());
services.AddSingleton<IHostedService, BusHostedService>();
return services;
}
解决方案
我最终从我的 WebApplicationFactory 中创建了一个方法,就像这样;
public void ConfigureTestServiceBus(Action<IServiceCollectionConfigurator> configurator)
{
this._configurator = configurator;
}
使我能够从派生的集成类构造函数中注册测试处理程序;
public Intg_GetCustomers(WebApplicationTestFactory<Startup> factory)
: base(factory)
{
factory.ConfigureTestServiceBus(c =>
{
c.AddConsumer<TestGetProductConsumer>();
});
}
当我调用我的扩展方法来添加 MassTransit 的 InMemory 实例时,将使用此配置器
public static IWebHostBuilder ConfigureTestServiceBus(this IWebHostBuilder webHostBuilder, Action<IServiceCollectionConfigurator> configurator)
{
return webHostBuilder
.ConfigureTestServices(services =>
{
// UseInMemoryServiceBus DI for MassTransit.
services.AddMassTransit(c =>
{
configurator?.Invoke(c);
// Add bus to the container.
c.AddBus(provider =>
{
var control = Bus.Factory.CreateUsingInMemory(cfg =>
{
cfg.ConfigureEndpoints(provider);
});
control.Start();
return control;
});
});
services.AddSingleton<IMessageDataRepository, InMemoryMessageDataRepository>();
});
}
推荐阅读
- oracle - 如何查找不同 Oracle APPS 模块的 API?
- javascript - 无法在 request.post 方法中设置状态
- java - 创建一个spring bean,它调用带有标题的url
- ocaml - OCaml:两个函数的内部“让”
- azure-application-insights - Application Insights Analytics 中的单独 apdex 阈值
- scala - 如何禁用 Akka WebSocket 服务器上的消息缓冲?
- c# - ASP.net Core中主机和服务器的区别和关系
- vba - 仅匹配对象名称的一部分
- bash - Bash - 以 CIDR 表示法转换网络掩码?
- c# - ASP.NET Core 2.0 - 提供没有扩展名的文件