using Dpz.Core.Entity.Base;
using Dpz.Core.MessageQueue.Abstractions;
using Dpz.Core.MessageQueue.Extensions;
using Dpz.Core.MessageQueue.RabbitMQ;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Moq;

namespace Dpz.Core.MessageQueue.Test.RabbitMQ;

public class RabbitMQPublisherRegistrationTests
{
    [Fact]
    public async Task AddRabbitMQ_ShouldResolveTypedPublisherFromDi()
    {
        var services = new ServiceCollection();
        services.AddLogging();

        var configuration = new ConfigurationBuilder()
            .AddInMemoryCollection(
                new Dictionary<string, string?>
                {
                    ["RabbitMQ:HostName"] = "host",
                    ["RabbitMQ:Port"] = "5672",
                    ["RabbitMQ:UserName"] = "guest",
                    ["RabbitMQ:Password"] = "guest",
                    ["RabbitMQ:VirtualHost"] = "/",
                }
            )
            .Build();

        services.AddRabbitMQ(configuration);

        await using var provider = services.BuildServiceProvider();

        var publisher = provider.GetRequiredService<IMessagePublisher<SampleMessage>>();

        Assert.IsType<RabbitMQPublisher<SampleMessage>>(publisher);
    }

    [Fact]
    public async Task PublisherCanBeConstructedUsingDiWithMockedDependencies()
    {
        var services = new ServiceCollection();

        var connectionFactory = new Mock<IRabbitMQConnectionFactory>();
        var routingConvention = new Mock<IMessageRoutingConvention>();
        routingConvention
            .Setup(x => x.GetExchangeName<SampleMessage>())
            .Returns("dpz.sample.exchange");
        routingConvention
            .Setup(x => x.GetExchangeType<SampleMessage>())
            .Returns(Enums.ExchangeType.Topic);
        routingConvention.Setup(x => x.GetRoutingKey<SampleMessage>()).Returns("sample.message.#");
        routingConvention
            .Setup(x => x.GetQueueName<SampleMessage>())
            .Returns("dpz.sample.message.queue");

        services.AddSingleton(connectionFactory.Object);
        services.AddSingleton(routingConvention.Object);
        services.AddSingleton<ILogger<RabbitMQPublisher<SampleMessage>>>(_ =>
            Microsoft
                .Extensions
                .Logging
                .Abstractions
                .NullLogger<RabbitMQPublisher<SampleMessage>>
                .Instance
        );
        services.AddSingleton<IMessagePublisher<SampleMessage>, RabbitMQPublisher<SampleMessage>>();

        await using var provider = services.BuildServiceProvider();

        var publisher = provider.GetRequiredService<IMessagePublisher<SampleMessage>>();
        Assert.NotNull(publisher);
    }

    private sealed class SampleMessage : MessageBase { }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这是一个用于测试 RabbitMQ 消息发布器注册和依赖注入的单元测试文件。让我详细解释一下这段代码:

类概述

RabbitMQPublisherRegistrationTests 是一个测试类,专门测试 RabbitMQ 消息发布器在依赖注入容器中的注册和解析功能。

测试方法分析

1. AddRabbitMQ_ShouldResolveTypedPublisherFromDi 测试

这个测试验证了 RabbitMQ 扩展方法能够正确注册服务并从 DI 容器中解析出正确的发布器实例:

测试步骤:

  • 创建 ServiceCollection 并添加日志服务
  • 通过内存配置构建 RabbitMQ 连接配置(主机、端口、用户名、密码、虚拟主机)
  • 调用 AddRabbitMQ 扩展方法注册 RabbitMQ 相关服务
  • 从 DI 容器中解析 IMessagePublisher<SampleMessage>
  • 断言解析出的实例类型是 RabbitMQPublisher<SampleMessage>

验证目标: 确保 RabbitMQ 扩展方法正确注册了类型化的消息发布器。

2. PublisherCanBeConstructedUsingDiWithMockedDependencies 测试

这个测试验证了使用模拟依赖项可以成功构造 RabbitMQ 发布器:

测试步骤:

  • 创建模拟的 IRabbitMQConnectionFactory 连接工厂
  • 创建模拟的 IMessageRoutingConvention 路由约定,并设置:
    • 交换机名称:"dpz.sample.exchange"
    • 交换机类型:Topic
    • 路由键:"sample.message.#"
    • 队列名称:"dpz.sample.message.queue"
  • 手动注册所有依赖项到 DI 容器
  • 注册 RabbitMQPublisher<SampleMessage> 作为 IMessagePublisher<SampleMessage> 的实现
  • 从容器中解析发布器实例并验证不为 null

验证目标: 确保 RabbitMQ 发布器可以通过依赖注入正确构造,即使使用的是模拟依赖项。

辅助类

private sealed class SampleMessage : MessageBase { }

这是一个简单的测试消息类,继承自 MessageBase,用作泛型类型参数。

技术要点

  1. 依赖注入测试:展示了如何测试 DI 容器的服务注册和解析
  2. 配置管理:使用内存配置提供者来模拟 RabbitMQ 配置
  3. 模拟对象:使用 Moq 框架创建模拟依赖项,实现单元测试的隔离
  4. 泛型服务:测试了泛型消息发布器服务的注册和解析
  5. 资源管理:使用 await using 确保服务提供者正确释放

这些测试确保了 RabbitMQ 消息队列组件能够正确集成到依赖注入系统中,为消息发布功能提供可靠的基础设施。

评论加载中...