@@ -19,6 +19,7 @@ public class QueueServiceTests
1919 const string DefaultExchangeName = "exchange.name" ;
2020 const string FirstRoutingKey = "first.routing.key" ;
2121 const string SecondRoutingKey = "second.routing.key" ;
22+ const int RequeueAttempts = 4 ;
2223
2324 [ Fact ]
2425 public async Task ShouldProperlyPublishAndConsumeMessages ( )
@@ -47,7 +48,7 @@ public async Task ShouldProperlyPublishAndConsumeMessages()
4748 . AddAsyncMessageHandlerTransient < StubAsyncMessageHandler > ( SecondRoutingKey )
4849 . AddAsyncNonCyclicMessageHandlerTransient < StubAsyncNonCyclicMessageHandler > ( SecondRoutingKey ) ;
4950
50- var serviceProvider = serviceCollection . BuildServiceProvider ( ) ;
51+ await using var serviceProvider = serviceCollection . BuildServiceProvider ( ) ;
5152 var queueService = serviceProvider . GetRequiredService < IQueueService > ( ) ;
5253 queueService . StartConsuming ( ) ;
5354
@@ -66,6 +67,50 @@ public async Task ShouldProperlyPublishAndConsumeMessages()
6667 resetEvent . WaitOne ( _globalTestsTimeout ) ;
6768 callerMock . Verify ( x => x . CallAsync ( It . IsAny < string > ( ) ) , Times . Exactly ( 2 ) ) ;
6869 }
70+
71+ [ Fact ]
72+ public async Task ShouldProperlyRequeueMessages ( )
73+ {
74+ var connectionFactoryMock = new Mock < RabbitMqConnectionFactory > { CallBase = true }
75+ . As < IRabbitMqConnectionFactory > ( ) ;
76+
77+ AsyncEventingBasicConsumer consumer = null ;
78+ connectionFactoryMock . Setup ( x => x . CreateConsumer ( It . IsAny < IModel > ( ) ) )
79+ . Returns < IModel > ( channel =>
80+ {
81+ consumer = new AsyncEventingBasicConsumer ( channel ) ;
82+ return consumer ;
83+ } ) ;
84+
85+ var callerMock = new Mock < IStubCaller > ( ) ;
86+
87+ var serviceCollection = new ServiceCollection ( ) ;
88+ serviceCollection
89+ . AddSingleton ( connectionFactoryMock . Object )
90+ . AddSingleton ( callerMock . Object )
91+ . AddRabbitMqClient ( GetClientOptions ( ) )
92+ . AddConsumptionExchange ( DefaultExchangeName , GetExchangeOptions ( ) )
93+ . AddMessageHandlerTransient < StubExceptionMessageHandler > ( FirstRoutingKey ) ;
94+
95+ await using var serviceProvider = serviceCollection . BuildServiceProvider ( ) ;
96+ var queueService = serviceProvider . GetRequiredService < IQueueService > ( ) ;
97+ queueService . StartConsuming ( ) ;
98+
99+ using var resetEvent = new AutoResetEvent ( false ) ;
100+ consumer . Received += ( sender , @event ) =>
101+ {
102+ resetEvent . Set ( ) ;
103+ return Task . CompletedTask ;
104+ } ;
105+
106+ await queueService . SendAsync ( new { Message = "message" } , DefaultExchangeName , FirstRoutingKey ) ;
107+
108+ for ( var i = 1 ; i <= RequeueAttempts + 1 ; i ++ )
109+ {
110+ resetEvent . WaitOne ( _globalTestsTimeout ) ;
111+ }
112+ callerMock . Verify ( x => x . Call ( It . IsAny < string > ( ) ) , Times . Exactly ( RequeueAttempts + 1 ) ) ;
113+ }
69114
70115 static RabbitMqClientOptions GetClientOptions ( ) =>
71116 new RabbitMqClientOptions
@@ -82,6 +127,8 @@ static RabbitMqExchangeOptions GetExchangeOptions() =>
82127 {
83128 Type = "direct" ,
84129 DeadLetterExchange = "exchange.dlx" ,
130+ RequeueAttempts = RequeueAttempts ,
131+ RequeueTimeoutMilliseconds = 50 ,
85132 Queues = new List < RabbitMqQueueOptions >
86133 {
87134 new RabbitMqQueueOptions
0 commit comments