如何在Xunit中使用Quartz进行集成测试

问题描述 投票:0回答:1

我需要测试 Quartz Job。 Quarts 作业的作用是触发改变用户平衡的领域事件。手动它工作正常。

测试中的问题是Job根本不处理Outbox消息。 ProcessedOnUtc 保持为空。

测试:

 [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: 
    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;
    });

工作

 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();
    }
c# .net domain-driven-design xunit quartz
1个回答
0
投票

试试这个。

[Fact]
public async Task Should_WinAuction_When_BuyoutPrice()
{
    // Arrange
    var user = User.Create(Guid.NewGuid(), "example", "[email protected]");
    var userTwo = User.Create(Guid.NewGuid(), "example2", "[email protected]");
    _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);

    // Act
    await TriggerQuartzJobManually();

    // Assert
    var updatedUser = DbContext.Users.FirstOrDefault(u => u.Id == userTwo.Id);
    Assert.True(updatedUser.Balance != 10000);
}

private async Task TriggerQuartzJobManually()
{
    // Create and start scheduler manually
    ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
    IScheduler scheduler = await schedulerFactory.GetScheduler();
    await scheduler.Start();

    // Define the job and trigger
    var jobDetail = JobBuilder.Create<ProcessOutboxMessages>()
        .WithIdentity("ProcessOutboxMessages")
        .Build();

    var trigger = TriggerBuilder.Create()
        .WithIdentity("ProcessOutboxMessagesTrigger")
        .StartNow()
        .WithSimpleSchedule(x => x.WithIntervalInSeconds(1).RepeatForever())
        .Build();

    await scheduler.ScheduleJob(jobDetail, trigger);

    // Wait enough time for the job to be triggered and processed
    await Task.Delay(5000);

    // Stop the scheduler
    await scheduler.Shutdown();
}
© www.soinside.com 2019 - 2024. All rights reserved.