I need to test Quartz Job. The role of the quarts job is to fire Domain Event which changes user balance. Manually it works fine.
The problem in test is that Job does not process Outbox message at all.
ProcessedOnUtc stays null.
Test:
[Fact]
public async Task Should_WinAuction_When_BuyoutPrice()
{
var user = User.Create(Guid.NewGuid(), "example", "[email protected]");
var userTwo = User.Create(Guid.NewGuid(), "example2", "[email protected]");
var oldBalance = user.Balance;
_userRepository.Add(user);
_userRepository.Add(userTwo);
await UnitOfWork.SaveChangesAsync();
var auction = Auction.Create(Guid.NewGuid(), "example", "description", 10m, 11m, DateTime.Now, user.Id);
_auctionRepository.Add(auction);
await UnitOfWork.SaveChangesAsync();
var command = new PlaceBidCommand(11m, userTwo.Id, auction.Id);
var result = await Sender.Send(command);
Assert.True(result.IsSuccess);
var bid = await _bidRepository.GetByIdAsync(result.Data.BidId);
Assert.NotNull(bid);
Assert.Equal(userTwo.Id, auction.WinnerId);
await Task.Delay(5000);
var updatedUser = DbContext.Users.FirstOrDefault(u => u.Id == userTwo.Id);
Assert.True(updatedUser.Balance != 10000);
}
Quartz registration:
Quartz:
services.AddQuartz(options =>
{
var jobKey = JobKey.Create(nameof(ProcessOutboxMessages));
options.SchedulerId = Guid.NewGuid().ToString();
options.SchedulerName = "OutboxMessages";
options.AddJob<ProcessOutboxMessages>(jobKey)
.AddTrigger(trigger => trigger.ForJob(jobKey).WithSimpleSchedule(schedule =>
{
schedule.WithIntervalInSeconds(1);
schedule.RepeatForever();
}));
});
services.AddQuartzHostedService(options =>
{
options.WaitForJobsToComplete = true;
});
Job
public async Task Execute(IJobExecutionContext context)
{
var messages = await _dbContext.OutboxMessages
.Where(x => x.ProcessedOnUtc == null)
.Take(20)
.ToListAsync();
foreach (var message in messages)
{
IDomainEvent? domainEvent = JsonConvert.DeserializeObject<IDomainEvent>(message.Content, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });
if (domainEvent == null)
{
continue;
}
await _publisher.Publish(domainEvent);
message.ProcessedOnUtc = DateTime.UtcNow;
}
await _dbContext.SaveChangesAsync();
}