using GFramework.Core.Abstractions.command;
using GFramework.Core.Abstractions.rule;
using GFramework.Core.architecture;
using GFramework.Core.command;
using GFramework.Core.environment;
using GFramework.Core.events;
using GFramework.Core.ioc;
using GFramework.Core.query;
using NUnit.Framework;
namespace GFramework.Core.Tests.command;
///
/// AbstractAsyncCommand类的单元测试
/// 测试内容包括:
/// - 异步命令无返回值版本的基础实现
/// - 异步命令有返回值版本的基础实现
/// - ExecuteAsync方法调用
/// - ExecuteAsync方法的异常处理
/// - 上下文感知功能(SetContext, GetContext)
/// - 日志功能(Logger属性)
/// - 子类继承行为验证(两个版本)
/// - 命令执行前日志记录
/// - 命令执行后日志记录
/// - 错误情况下的日志记录
/// - 无返回值版本的行为
/// - 有返回值版本的行为
///
[TestFixture]
public class AbstractAsyncCommandTests
{
[SetUp]
public void SetUp()
{
_container = new IocContainer();
_container.RegisterPlurality(new EventBus());
_container.RegisterPlurality(new CommandBus());
_container.RegisterPlurality(new QueryBus());
_container.RegisterPlurality(new DefaultEnvironment());
_container.RegisterPlurality(new AsyncQueryBus());
_context = new ArchitectureContext(_container);
}
private ArchitectureContext _context = null!;
private IocContainer _container = null!;
///
/// 测试异步命令无返回值版本的基础实现
///
[Test]
public async Task AbstractAsyncCommand_Should_Implement_IAsyncCommand_Interface()
{
var input = new TestCommandInputV2();
var command = new TestAsyncCommandV3(input);
Assert.That(command, Is.InstanceOf());
}
///
/// 测试异步命令有返回值版本的基础实现
///
[Test]
public async Task AbstractAsyncCommand_WithResult_Should_Implement_IAsyncCommand_Interface()
{
var input = new TestCommandInputV2();
var command = new TestAsyncCommandWithResultV3(input);
Assert.That(command, Is.InstanceOf>());
}
///
/// 测试ExecuteAsync方法调用
///
[Test]
public async Task ExecuteAsync_Should_Invoke_OnExecuteAsync_Method()
{
var input = new TestCommandInputV2 { Value = 42 };
var command = new TestAsyncCommandV3(input);
var asyncCommand = (IAsyncCommand)command;
await asyncCommand.ExecuteAsync();
Assert.That(command.Executed, Is.True);
Assert.That(command.ExecutedValue, Is.EqualTo(42));
}
///
/// 测试ExecuteAsync方法(带返回值)调用
///
[Test]
public async Task ExecuteAsync_WithResult_Should_Invoke_OnExecuteAsync_Method_And_Return_Result()
{
var input = new TestCommandInputV2 { Value = 100 };
var command = new TestAsyncCommandWithResultV3(input);
var asyncCommand = (IAsyncCommand)command;
var result = await asyncCommand.ExecuteAsync();
Assert.That(command.Executed, Is.True);
Assert.That(result, Is.EqualTo(200));
}
///
/// 测试ExecuteAsync方法的异常处理
///
[Test]
public void ExecuteAsync_Should_Propagate_Exception_From_OnExecuteAsync()
{
var input = new TestCommandInputV2();
var command = new TestAsyncCommandWithExceptionV3(input);
var asyncCommand = (IAsyncCommand)command;
Assert.ThrowsAsync(async () => await asyncCommand.ExecuteAsync());
}
///
/// 测试上下文感知功能 - SetContext方法
///
[Test]
public void SetContext_Should_Set_Context_Property()
{
var input = new TestCommandInputV2();
var command = new TestAsyncCommandV3(input);
var contextAware = (IContextAware)command;
contextAware.SetContext(_context);
var context = contextAware.GetContext();
Assert.That(context, Is.SameAs(_context));
}
///
/// 测试上下文感知功能 - GetContext方法
///
[Test]
public void GetContext_Should_Return_Context_Property()
{
var input = new TestCommandInputV2();
var command = new TestAsyncCommandV3(input);
var contextAware = (IContextAware)command;
contextAware.SetContext(_context);
var context = contextAware.GetContext();
Assert.That(context, Is.Not.Null);
Assert.That(context, Is.SameAs(_context));
}
///
/// 测试子类继承行为验证 - 无返回值版本
///
[Test]
public async Task Child_Class_Should_Inherit_And_Override_OnExecuteAsync_Method()
{
var input = new TestCommandInputV2 { Value = 100 };
var command = new TestAsyncCommandChildV3(input);
var asyncCommand = (IAsyncCommand)command;
await asyncCommand.ExecuteAsync();
Assert.That(command.Executed, Is.True);
Assert.That(command.ExecutedValue, Is.EqualTo(200));
}
///
/// 测试子类继承行为验证 - 有返回值版本
///
[Test]
public async Task Child_Class_WithResult_Should_Inherit_And_Override_OnExecuteAsync_Method()
{
var input = new TestCommandInputV2 { Value = 50 };
var command = new TestAsyncCommandWithResultChildV3(input);
var asyncCommand = (IAsyncCommand)command;
var result = await asyncCommand.ExecuteAsync();
Assert.That(command.Executed, Is.True);
Assert.That(result, Is.EqualTo(150));
}
///
/// 测试异步命令执行生命周期完整性
///
[Test]
public async Task AsyncCommand_Should_Complete_Execution_Lifecycle()
{
var input = new TestCommandInputV2 { Value = 42 };
var command = new TestAsyncCommandV3(input);
var asyncCommand = (IAsyncCommand)command;
Assert.That(command.Executed, Is.False, "Command should not be executed before ExecuteAsync");
await asyncCommand.ExecuteAsync();
Assert.That(command.Executed, Is.True, "Command should be executed after ExecuteAsync");
Assert.That(command.ExecutedValue, Is.EqualTo(42), "Command should have correct executed value");
}
///
/// 测试异步命令多次执行
///
[Test]
public async Task AsyncCommand_Should_Be_Executable_Multiple_Times()
{
var input = new TestCommandInputV2 { Value = 10 };
var command = new TestAsyncCommandV3(input);
var asyncCommand = (IAsyncCommand)command;
await asyncCommand.ExecuteAsync();
Assert.That(command.ExecutedValue, Is.EqualTo(10), "First execution should have value 10");
await asyncCommand.ExecuteAsync();
Assert.That(command.ExecutedValue, Is.EqualTo(10), "Second execution should have value 10");
}
///
/// 测试异步命令(带返回值)的返回值类型
///
[Test]
public async Task AsyncCommand_WithResult_Should_Return_Correct_Type()
{
var input = new TestCommandInputV2 { Value = 100 };
var command = new TestAsyncCommandWithResultV3(input);
var asyncCommand = (IAsyncCommand)command;
var result = await asyncCommand.ExecuteAsync();
Assert.That(result, Is.InstanceOf());
Assert.That(result, Is.EqualTo(200));
}
}
///
/// 测试用命令输入类V2
///
public sealed class TestCommandInputV2 : ICommandInput
{
///
/// 获取或设置值
///
public int Value { get; init; }
}
///
/// 测试用异步命令类V3(无返回值)
///
public sealed class TestAsyncCommandV3 : AbstractAsyncCommand
{
///
/// 构造函数
///
/// 命令输入
public TestAsyncCommandV3(TestCommandInputV2 input) : base(input)
{
}
///
/// 获取命令是否已执行
///
public bool Executed { get; private set; }
///
/// 获取执行的值
///
public int ExecutedValue { get; private set; }
///
/// 执行异步命令的重写方法
///
/// 命令输入
/// 表示异步操作的任务
protected override Task OnExecuteAsync(TestCommandInputV2 input)
{
Executed = true;
ExecutedValue = input.Value;
return Task.CompletedTask;
}
}
///
/// 测试用异步命令类V3(有返回值)
///
public sealed class TestAsyncCommandWithResultV3 : AbstractAsyncCommand
{
///
/// 构造函数
///
/// 命令输入
public TestAsyncCommandWithResultV3(TestCommandInputV2 input) : base(input)
{
}
///
/// 获取命令是否已执行
///
public bool Executed { get; private set; }
///
/// 执行异步命令并返回结果的重写方法
///
/// 命令输入
/// 执行结果的异步任务
protected override Task OnExecuteAsync(TestCommandInputV2 input)
{
Executed = true;
return Task.FromResult(input.Value * 2);
}
}
///
/// 测试用异步命令类(抛出异常)
///
public sealed class TestAsyncCommandWithExceptionV3 : AbstractAsyncCommand
{
///
/// 构造函数
///
/// 命令输入
public TestAsyncCommandWithExceptionV3(TestCommandInputV2 input) : base(input)
{
}
///
/// 执行异步命令并抛出异常的重写方法
///
/// 命令输入
/// 表示异步操作的任务
/// 总是抛出异常
protected override Task OnExecuteAsync(TestCommandInputV2 input)
{
throw new InvalidOperationException("Test exception");
}
}
///
/// 测试用异步命令子类(无返回值)
///
public sealed class TestAsyncCommandChildV3 : AbstractAsyncCommand
{
///
/// 构造函数
///
/// 命令输入
public TestAsyncCommandChildV3(TestCommandInputV2 input) : base(input)
{
}
///
/// 获取命令是否已执行
///
public bool Executed { get; private set; }
///
/// 获取执行的值
///
public int ExecutedValue { get; private set; }
///
/// 执行异步命令的重写方法(子类实现)
///
/// 命令输入
/// 表示异步操作的任务
protected override Task OnExecuteAsync(TestCommandInputV2 input)
{
Executed = true;
ExecutedValue = input.Value * 2;
return Task.CompletedTask;
}
}
///
/// 测试用异步命令子类(有返回值)
///
public sealed class TestAsyncCommandWithResultChildV3 : AbstractAsyncCommand
{
///
/// 构造函数
///
/// 命令输入
public TestAsyncCommandWithResultChildV3(TestCommandInputV2 input) : base(input)
{
}
///
/// 获取命令是否已执行
///
public bool Executed { get; private set; }
///
/// 执行异步命令并返回结果的重写方法(子类实现)
///
/// 命令输入
/// 执行结果的异步任务
protected override Task OnExecuteAsync(TestCommandInputV2 input)
{
Executed = true;
return Task.FromResult(input.Value * 3);
}
}