我希望能夠使用 MassTransit 的記憶體實作將訊息從單元測驗發送到 ASP.Net Core 應用程式。記憶體中的實作很重要,因為實際應用程式使用 ActiveMQ,但我們希望在測驗期間用記憶體中的實作替換它。
我開始使用 .NET 5 從 VS2019 創建一個新的 ASP.Net Core API 專案,并將 MassTransit 添加到Startup如下:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApplicationWithMassTransit", Version = "v1" });
});
services.AddMassTransit(x =>
{
x.AddConsumer<MessageConsumer>();
x.UsingInMemory((context, cfg) =>
{
cfg.ConfigureEndpoints(context);
});
});
services.AddMassTransitHostedService(true);
}
該MessageConsumer如下所示:
public class MessageConsumer : IConsumer<Message>
{
readonly ILogger<MessageConsumer> _logger;
public MessageConsumer(ILogger<MessageConsumer> logger)
{
_logger = logger;
}
public Task Consume(ConsumeContext<Message> context)
{
_logger.LogInformation("Received Text: {Text}", context.Message.Text);
return Task.CompletedTask;
}
}
而Message看起來像這樣:
public class Message
{
public string Text { get; set; }
}
當我注入IPublishEndpoint到WeatherForecastController和當發送郵件GET使用完成的:
await _endpoint.Publish(new Message {Text = "Test message"});
一切都按預期作業。
但是現在我想從單元測驗向應用程式發送訊息。所以我創建了一個 XUnit 測驗專案并參考了 ASP.Net API 專案。測驗類如下所示:
public class UnitTest1
: IClassFixture<WebApplicationFactory<Startup>>
{
private readonly WebApplicationFactory<Startup> _factory;
public UnitTest1(WebApplicationFactory<Startup> factory)
{
_factory = factory;
}
[Fact]
public async Task SendMassTransitMessage()
{
var client = _factory.CreateClient();
using var scope = _factory.Services.CreateScope();
var bus = scope.ServiceProvider.GetRequiredService<IBus>();
await bus.Publish(new Message {Text = "Test message from test"});
}
}
當我運行測驗時,它成功了,但沒有呼叫消費者。在除錯視窗中,我得到以下堆疊跟蹤:
MassTransit: Information: Configured endpoint Message, Consumer: WebApplicationWithMassTransit.MessageConsumer
MassTransit: Information: Bus started: loopback://localhost/
MassTransit.ReceiveTransport: Error: R-FAULT loopback://localhost/Message af0f0000-50b6-c8f7-16d4-08d9affc5a91 WebApplicationWithMassTransit.Message WebApplicationWithMassTransit.MessageConsumer(00:00:00.0072326)
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'IServiceProvider'.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ThrowHelper.ThrowObjectDisposedException()
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.CreateScope(IServiceProvider provider)
at MassTransit.ExtensionsDependencyInjectionIntegration.ScopeProviders.DependencyInjectionConsumerScopeProvider.MassTransit.Scoping.IConsumerScopeProvider.GetScope[TConsumer,T](ConsumeContext`1 context)
at MassTransit.Scoping.ScopeConsumerFactory`1.Send[TMessage](ConsumeContext`1 context, IPipe`1 next)
at MassTransit.Pipeline.Filters.ConsumerMessageFilter`2.GreenPipes.IFilter<MassTransit.ConsumeContext<TMessage>>.Send(ConsumeContext`1 context, IPipe`1 next)
MassTransit: Information: Bus stopped: loopback://localhost/
是否可以從這樣的單元測驗中發送訊息?我可能做錯了什么?我試著解決IBus,IBusControl并IPublishEndpoint在幾個方面,有和沒有創建一個范圍。
uj5u.com熱心網友回復:
您正在等待發布,但此時,測驗退出并開始拆除應用程式。您需要等到消費者完成,因為它是異步呼叫的。使用記憶體中測驗工具時,有一些監視器可用于等待直到沒有總線活動,但我不知道在上面的場景中如何做到這一點。
您希望如何斷言消費者實際上完成了作業?
為了證明這一點,添加一個簡單的await Task.Delay(1000),看看消費者是否執行。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/366156.html
