public async Task ProcessWithTrueOnAllSucceed()
        {
            // Arrange
            var uow       = new Mock <IOutboxUnitOfWork>();
            var sender    = new Mock <IOutboxSender>();
            var ilogger   = new Mock <ILogger <OutboxMessageProcessor> >();
            var processor = new OutboxMessageProcessor(uow.Object, sender.Object, ilogger.Object);
            var cts       = new CancellationTokenSource();
            var message   = new Mock <IOutboxMessage>();

            int callOrder = 0;

            sender.Setup(x => x.SendAsync(message.Object, cts.Token)).Callback(() => callOrder++.Should().Be(0));
            uow.Setup(x => x.RemoveOutboxMessageAsync(message.Object, cts.Token)).Callback(() => callOrder++.Should().Be(1));
            uow.Setup(x => x.SaveAsync(cts.Token)).Callback(() => callOrder++.Should().Be(2));


            bool result = true;
            // Act
            var exception = await Record.ExceptionAsync(async() => result = await processor.TryProcessAsync(message.Object, cts.Token));

            // Assert
            exception.Should().BeNull();
            result.Should().BeTrue();

            sender.Verify(x => x.SendAsync(message.Object, cts.Token), Times.Once);
            uow.Verify(x => x.RemoveOutboxMessageAsync(message.Object, cts.Token), Times.Once);
            uow.Verify(x => x.SaveAsync(cts.Token), Times.Once);
        }
        public async Task CantProcessNullMessageAsync()
        {
            // Arrange
            var            uow       = new Mock <IOutboxUnitOfWork>();
            var            sender    = new Mock <IOutboxSender>();
            var            ilogger   = new Mock <ILogger <OutboxMessageProcessor> >();
            var            processor = new OutboxMessageProcessor(uow.Object, sender.Object, ilogger.Object);
            var            cts       = new CancellationTokenSource();
            IOutboxMessage message   = null !;

            // Act
            var exception = await Record.ExceptionAsync(async() => _ = await processor.TryProcessAsync(message, cts.Token));

            // Assert
            exception.Should().NotBeNull().And.BeOfType <ArgumentNullException>();
        }
        public async Task ProcessWithFalseOnSaveError()
        {
            // Arrange
            var uow       = new Mock <IOutboxUnitOfWork>();
            var sender    = new Mock <IOutboxSender>();
            var ilogger   = new Mock <ILogger <OutboxMessageProcessor> >();
            var processor = new OutboxMessageProcessor(uow.Object, sender.Object, ilogger.Object);
            var cts       = new CancellationTokenSource();
            var message   = new Mock <IOutboxMessage>();

            uow.Setup(x => x.SaveAsync(cts.Token)).ThrowsAsync(new Exception());


            bool result = true;
            // Act
            var exception = await Record.ExceptionAsync(async() => result = await processor.TryProcessAsync(message.Object, cts.Token));

            // Assert
            exception.Should().BeNull();
            result.Should().BeFalse();
        }