test(cqrs): 补充注册服务边界测试

- 补充空程序集输入时不触发 registrar 的回归测试
- 验证忽略空项后按稳定程序集键排序并去重的注册顺序
- 验证跨调用跳过已注册程序集键时仍继续处理剩余新程序集
This commit is contained in:
gewuyou 2026-05-12 08:36:18 +08:00 committed by GeWuYou
parent ef4d3d5ddf
commit 75e7785592

View File

@ -13,6 +13,24 @@ namespace GFramework.Cqrs.Tests.Cqrs;
[TestFixture]
internal sealed class CqrsRegistrationServiceTests
{
/// <summary>
/// 验证空程序集输入不会触发底层注册,也不会产生重复跳过日志。
/// </summary>
[Test]
public void RegisterHandlers_Should_Not_Invoke_Registrar_When_Assemblies_Are_Empty()
{
var logger = new TestLogger("DefaultCqrsRegistrationService", LogLevel.Debug);
var registrar = new Mock<ICqrsHandlerRegistrar>(MockBehavior.Strict);
var service = CqrsRuntimeFactory.CreateRegistrationService(registrar.Object, logger);
service.RegisterHandlers([]);
registrar.Verify(
static currentRegistrar => currentRegistrar.RegisterHandlers(It.IsAny<IEnumerable<Assembly>>()),
Times.Never);
Assert.That(logger.Logs, Has.Count.EqualTo(0));
}
/// <summary>
/// 验证同一次调用内出现重复程序集键时,底层注册器只会接收到一次注册请求。
/// </summary>
@ -87,6 +105,82 @@ internal sealed class CqrsRegistrationServiceTests
});
}
/// <summary>
/// 验证协调器会忽略空项,并按稳定程序集键排序后仅注册当前调用内的唯一程序集。
/// </summary>
[Test]
public void RegisterHandlers_Should_Ignore_Null_Entries_And_Register_Unique_Assemblies_In_Stable_Key_Order()
{
var logger = new TestLogger("DefaultCqrsRegistrationService", LogLevel.Debug);
var registrar = new Mock<ICqrsHandlerRegistrar>(MockBehavior.Strict);
var assemblyC = CreateAssembly("GFramework.Cqrs.Tests.Sorting.C, Version=1.0.0.0");
var assemblyA = CreateAssembly("GFramework.Cqrs.Tests.Sorting.A, Version=1.0.0.0");
var duplicateAssemblyA = CreateAssembly("GFramework.Cqrs.Tests.Sorting.A, Version=1.0.0.0");
var assemblyB = CreateAssembly("GFramework.Cqrs.Tests.Sorting.B, Version=1.0.0.0");
var registeredAssemblies = new List<Assembly>();
registrar
.Setup(static currentRegistrar => currentRegistrar.RegisterHandlers(It.IsAny<IEnumerable<Assembly>>()))
.Callback<IEnumerable<Assembly>>(assemblies => registeredAssemblies.AddRange(assemblies));
var service = CqrsRuntimeFactory.CreateRegistrationService(registrar.Object, logger);
service.RegisterHandlers([assemblyC.Object, null!, assemblyA.Object, duplicateAssemblyA.Object, assemblyB.Object, null!]);
registrar.Verify(
static currentRegistrar => currentRegistrar.RegisterHandlers(It.IsAny<IEnumerable<Assembly>>()),
Times.Exactly(3));
Assert.Multiple(() =>
{
Assert.That(
registeredAssemblies,
Is.EqualTo([assemblyA.Object, assemblyB.Object, assemblyC.Object]));
Assert.That(logger.Logs, Has.Count.EqualTo(0));
});
}
/// <summary>
/// 验证跨调用遇到已注册程序集键时,协调器会跳过重复项,同时继续按稳定程序集键顺序处理剩余新程序集。
/// </summary>
[Test]
public void RegisterHandlers_Should_Skip_Previously_Registered_Keys_And_Keep_Stable_Order_For_Remaining_Assemblies()
{
var logger = new TestLogger("DefaultCqrsRegistrationService", LogLevel.Debug);
var registrar = new Mock<ICqrsHandlerRegistrar>(MockBehavior.Strict);
var firstAssembly = CreateAssembly("GFramework.Cqrs.Tests.Sorting.B, Version=1.0.0.0");
var duplicateAssembly = CreateAssembly("GFramework.Cqrs.Tests.Sorting.B, Version=1.0.0.0");
var assemblyC = CreateAssembly("GFramework.Cqrs.Tests.Sorting.C, Version=1.0.0.0");
var assemblyA = CreateAssembly("GFramework.Cqrs.Tests.Sorting.A, Version=1.0.0.0");
var registeredAssemblies = new List<Assembly>();
registrar
.Setup(static currentRegistrar => currentRegistrar.RegisterHandlers(It.IsAny<IEnumerable<Assembly>>()))
.Callback<IEnumerable<Assembly>>(assemblies => registeredAssemblies.AddRange(assemblies));
var service = CqrsRuntimeFactory.CreateRegistrationService(registrar.Object, logger);
service.RegisterHandlers([firstAssembly.Object]);
service.RegisterHandlers([assemblyC.Object, duplicateAssembly.Object, assemblyA.Object]);
registrar.Verify(
static currentRegistrar => currentRegistrar.RegisterHandlers(It.IsAny<IEnumerable<Assembly>>()),
Times.Exactly(3));
Assert.Multiple(() =>
{
Assert.That(
registeredAssemblies,
Is.EqualTo([firstAssembly.Object, assemblyA.Object, assemblyC.Object]));
var debugMessages = logger.Logs
.Where(static log => log.Level == LogLevel.Debug)
.Select(static log => log.Message)
.ToArray();
Assert.That(debugMessages, Has.Length.EqualTo(1));
Assert.That(
debugMessages[0],
Does.Contain("GFramework.Cqrs.Tests.Sorting.B, Version=1.0.0.0"));
});
}
/// <summary>
/// 验证当 <see cref="Assembly.FullName" /> 缺失时,协调器会退化到 <see cref="AssemblyName.Name" /> 作为稳定程序集键。
/// </summary>