mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-08 17:44:29 +08:00
- 修复 legacy 同步 bridge 的 runtime 等待方式,统一通过共享 helper 隔离同步上下文并收口重复 dispatch-context 解析逻辑 - 补充 legacy async command bridge 的取消可见性,并更新 ICqrsRuntime 与相关入口的契约说明 - 新增 bridge 回归测试并更新 cqrs-rewrite active tracking,覆盖同步上下文隔离、测试容器释放与取消语义
107 lines
3.4 KiB
C#
107 lines
3.4 KiB
C#
// Copyright (c) 2025-2026 GeWuYou
|
||
// SPDX-License-Identifier: Apache-2.0
|
||
|
||
using GFramework.Core.Query;
|
||
using GFramework.Core.Tests.Architectures;
|
||
using GFramework.Core.Tests.Command;
|
||
|
||
namespace GFramework.Core.Tests.Query;
|
||
|
||
/// <summary>
|
||
/// 查询总线测试类,用于测试QueryBus的功能和异常处理
|
||
/// </summary>
|
||
[TestFixture]
|
||
public class QueryExecutorTests
|
||
{
|
||
/// <summary>
|
||
/// 测试设置方法,在每个测试方法执行前初始化查询总线实例
|
||
/// </summary>
|
||
[SetUp]
|
||
public void SetUp()
|
||
{
|
||
_queryExecutor = new QueryExecutor();
|
||
}
|
||
|
||
private QueryExecutor _queryExecutor = null!;
|
||
|
||
/// <summary>
|
||
/// 测试Send方法是否能正确返回查询结果
|
||
/// 验证当传入有效查询对象时,能够得到预期的计算结果
|
||
/// </summary>
|
||
[Test]
|
||
public void Send_Should_Return_Query_Result()
|
||
{
|
||
var input = new TestQueryInput { Value = 10 };
|
||
var query = new TestQuery(input);
|
||
|
||
var result = _queryExecutor.Send(query);
|
||
|
||
Assert.That(result, Is.EqualTo(20));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 测试Send方法在传入空查询对象时是否会抛出ArgumentNullException异常
|
||
/// 验证参数验证功能的正确性
|
||
/// </summary>
|
||
[Test]
|
||
public void Send_WithNullQuery_Should_ThrowArgumentNullException()
|
||
{
|
||
Assert.Throws<ArgumentNullException>(() => _queryExecutor.Send<int>(null!));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 测试Send方法是否能正确返回字符串类型的查询结果
|
||
/// 验证不同返回类型的支持情况
|
||
/// </summary>
|
||
[Test]
|
||
public void Send_WithStringResult_Should_Return_String()
|
||
{
|
||
var input = new TestQueryInput { Value = 5 };
|
||
var query = new TestStringQuery(input);
|
||
|
||
var result = _queryExecutor.Send(query);
|
||
|
||
Assert.That(result, Is.EqualTo("Result: 10"));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证 legacy 同步查询桥接会在线程池上等待 runtime,
|
||
/// 避免直接复用调用方的同步上下文。
|
||
/// </summary>
|
||
[Test]
|
||
public void Send_Should_Bridge_Through_Runtime_Without_Reusing_Caller_SynchronizationContext()
|
||
{
|
||
var runtime = new RecordingCqrsRuntime(static _ => 24);
|
||
var executor = new QueryExecutor(runtime);
|
||
var query = new ContextAwareLegacyQuery(24);
|
||
var expectedContext = new TestArchitectureContextBaseStub();
|
||
((GFramework.Core.Abstractions.Rule.IContextAware)query).SetContext(expectedContext);
|
||
var originalContext = SynchronizationContext.Current;
|
||
|
||
try
|
||
{
|
||
SynchronizationContext.SetSynchronizationContext(new TestLegacySynchronizationContext());
|
||
|
||
var result = executor.Send(query);
|
||
|
||
Assert.Multiple(() =>
|
||
{
|
||
Assert.That(result, Is.EqualTo(24));
|
||
Assert.That(runtime.LastRequest, Is.TypeOf<GFramework.Core.Cqrs.LegacyQueryDispatchRequest>());
|
||
Assert.That(runtime.ObservedSynchronizationContextType, Is.Null);
|
||
});
|
||
}
|
||
finally
|
||
{
|
||
SynchronizationContext.SetSynchronizationContext(originalContext);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 为同步 bridge 测试提供最小架构上下文替身。
|
||
/// </summary>
|
||
private sealed class TestArchitectureContextBaseStub : TestArchitectureContextBase
|
||
{
|
||
}
|
||
}
|