public SqlCommandPublisher(
     Func <ProcessManagerDbContext> dbContextFactory,
     IMessageSerializer serializer,
     IMessageBus messageBus,
     IScheduledMessageBus scheduledMessageBus)
 {
     _dbContextFactory    = dbContextFactory ?? throw new ArgumentNullException(nameof(dbContextFactory));
     _serializer          = serializer ?? throw new ArgumentNullException(nameof(serializer));
     _messageBus          = messageBus ?? throw new ArgumentNullException(nameof(messageBus));
     _scheduledMessageBus = scheduledMessageBus ?? throw new ArgumentNullException(nameof(scheduledMessageBus));
 }
        public async Task given_scheduled_message_bus_fails_FlushCommands_deletes_no_scheduled_command()
        {
            // Arrange
            var serializer        = new JsonMessageSerializer();
            var processManager    = new FooProcessManager();
            var fixture           = new Fixture();
            var scheduledCommands = new List <PendingScheduledCommand>(
                from command in fixture.CreateMany <FooCommand>()
                let envelope = new Envelope(command)
                               let scheduledEnvelope = new ScheduledEnvelope(envelope, fixture.Create <DateTimeOffset>())
                                                       select PendingScheduledCommand.FromScheduledEnvelope(processManager, scheduledEnvelope, serializer));

            using (var db = new FooProcessManagerDbContext())
            {
                db.PendingScheduledCommands.AddRange(scheduledCommands);
                await db.SaveChangesAsync();
            }

            Guid poisonedMessageId = (from c in scheduledCommands
                                      orderby c.GetHashCode()
                                      select c.MessageId).First();

            IScheduledMessageBus scheduledMessageBus = Mock.Of <IScheduledMessageBus>();
            var exception = new InvalidOperationException();

            Mock.Get(scheduledMessageBus)
            .Setup(x => x.Send(It.Is <ScheduledEnvelope>(p => p.Envelope.MessageId == poisonedMessageId), CancellationToken.None))
            .ThrowsAsync(exception);

            var sut = new SqlCommandPublisher(
                () => new FooProcessManagerDbContext(),
                serializer,
                Mock.Of <IMessageBus>(),
                scheduledMessageBus);

            // Act
            Func <Task> action = () => sut.FlushCommands(processManager.Id, CancellationToken.None);

            // Assert
            action.ShouldThrow <InvalidOperationException>().Which.Should().BeSameAs(exception);
            using (var db = new FooProcessManagerDbContext())
            {
                IQueryable <PendingScheduledCommand> query = from c in db.PendingScheduledCommands
                                                             where c.ProcessManagerId == processManager.Id
                                                             select c;
                List <PendingScheduledCommand> actual = await query.ToListAsync();

                actual.ShouldAllBeEquivalentTo(scheduledCommands, opts => opts.RespectingRuntimeTypes());
            }
        }