mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-23 19:24:29 +08:00
doc(core-tests): 添加架构配置和上下文相关单元测试添加注释
- 添加注释 - [skip ci]
This commit is contained in:
parent
70e16724c9
commit
7246fef061
@ -7,17 +7,31 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.architecture;
|
||||
|
||||
/// <summary>
|
||||
/// ArchitectureConfiguration类的单元测试
|
||||
/// 测试内容包括:
|
||||
/// - 构造函数默认值
|
||||
/// - LoggerProperties默认配置(ConsoleLoggerFactoryProvider + Info级别)
|
||||
/// - ArchitectureProperties默认配置(AllowLateRegistration=false, StrictPhaseValidation=true)
|
||||
/// - 自定义配置替换
|
||||
/// - LoggerProperties独立修改
|
||||
/// - ArchitectureProperties独立修改
|
||||
/// - IArchitectureConfiguration接口实现验证
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class ArchitectureConfigurationTests
|
||||
{
|
||||
private ArchitectureConfiguration? _configuration;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_configuration = new ArchitectureConfiguration();
|
||||
}
|
||||
|
||||
private ArchitectureConfiguration? _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// 测试构造函数是否正确初始化LoggerProperties
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Constructor_Should_Initialize_LoggerProperties_With_Default_Values()
|
||||
{
|
||||
@ -25,121 +39,154 @@ public class ArchitectureConfigurationTests
|
||||
Assert.That(_configuration!.LoggerProperties, Is.Not.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试LoggerProperties默认使用ConsoleLoggerFactoryProvider
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void LoggerProperties_Should_Use_ConsoleLoggerFactoryProvider_By_Default()
|
||||
{
|
||||
Assert.That(_configuration!.LoggerProperties.LoggerFactoryProvider,
|
||||
Assert.That(_configuration!.LoggerProperties.LoggerFactoryProvider,
|
||||
Is.InstanceOf<ConsoleLoggerFactoryProvider>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试LoggerProperties默认使用Info日志级别
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void LoggerProperties_Should_Use_Info_LogLevel_By_Default()
|
||||
{
|
||||
var consoleProvider = _configuration!.LoggerProperties.LoggerFactoryProvider
|
||||
var consoleProvider = _configuration!.LoggerProperties.LoggerFactoryProvider
|
||||
as ConsoleLoggerFactoryProvider;
|
||||
|
||||
|
||||
Assert.That(consoleProvider, Is.Not.Null);
|
||||
Assert.That(consoleProvider!.MinLevel, Is.EqualTo(LogLevel.Info));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ArchitectureProperties的AllowLateRegistration默认为false
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ArchitectureProperties_Should_Have_AllowLateRegistration_Set_To_False_By_Default()
|
||||
{
|
||||
Assert.That(_configuration!.ArchitectureProperties.AllowLateRegistration,
|
||||
Assert.That(_configuration!.ArchitectureProperties.AllowLateRegistration,
|
||||
Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ArchitectureProperties的StrictPhaseValidation默认为true
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ArchitectureProperties_Should_Have_StrictPhaseValidation_Set_To_True_By_Default()
|
||||
{
|
||||
Assert.That(_configuration!.ArchitectureProperties.StrictPhaseValidation,
|
||||
Assert.That(_configuration!.ArchitectureProperties.StrictPhaseValidation,
|
||||
Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试LoggerProperties可以被自定义配置替换
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void LoggerProperties_Should_Be_Replaced_With_Custom_Configuration()
|
||||
{
|
||||
var customProvider = new ConsoleLoggerFactoryProvider { MinLevel = LogLevel.Debug };
|
||||
var customLoggerProperties = new LoggerProperties
|
||||
{
|
||||
LoggerFactoryProvider = customProvider
|
||||
var customLoggerProperties = new LoggerProperties
|
||||
{
|
||||
LoggerFactoryProvider = customProvider
|
||||
};
|
||||
|
||||
|
||||
_configuration!.LoggerProperties = customLoggerProperties;
|
||||
|
||||
|
||||
Assert.That(_configuration.LoggerProperties, Is.SameAs(customLoggerProperties));
|
||||
Assert.That(_configuration.LoggerProperties.LoggerFactoryProvider,
|
||||
Assert.That(_configuration.LoggerProperties.LoggerFactoryProvider,
|
||||
Is.InstanceOf<ConsoleLoggerFactoryProvider>());
|
||||
var currentProvider = _configuration.LoggerProperties.LoggerFactoryProvider
|
||||
var currentProvider = _configuration.LoggerProperties.LoggerFactoryProvider
|
||||
as ConsoleLoggerFactoryProvider;
|
||||
Assert.That(currentProvider!.MinLevel, Is.EqualTo(LogLevel.Debug));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ArchitectureProperties可以被自定义配置替换
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ArchitectureProperties_Should_Be_Replaced_With_Custom_Configuration()
|
||||
{
|
||||
var customProperties = new ArchitectureProperties
|
||||
{
|
||||
var customProperties = new ArchitectureProperties
|
||||
{
|
||||
AllowLateRegistration = true,
|
||||
StrictPhaseValidation = false
|
||||
};
|
||||
|
||||
|
||||
_configuration!.ArchitectureProperties = customProperties;
|
||||
|
||||
|
||||
Assert.That(_configuration.ArchitectureProperties, Is.SameAs(customProperties));
|
||||
Assert.That(_configuration.ArchitectureProperties.AllowLateRegistration,
|
||||
Assert.That(_configuration.ArchitectureProperties.AllowLateRegistration,
|
||||
Is.True);
|
||||
Assert.That(_configuration.ArchitectureProperties.StrictPhaseValidation,
|
||||
Assert.That(_configuration.ArchitectureProperties.StrictPhaseValidation,
|
||||
Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试LoggerProperties可以独立修改
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void LoggerProperties_Should_Be_Modifiable_Independently()
|
||||
{
|
||||
var originalProvider = _configuration!.LoggerProperties.LoggerFactoryProvider
|
||||
var originalProvider = _configuration!.LoggerProperties.LoggerFactoryProvider
|
||||
as ConsoleLoggerFactoryProvider;
|
||||
|
||||
|
||||
originalProvider!.MinLevel = LogLevel.Debug;
|
||||
|
||||
var modifiedProvider = _configuration.LoggerProperties.LoggerFactoryProvider
|
||||
|
||||
var modifiedProvider = _configuration.LoggerProperties.LoggerFactoryProvider
|
||||
as ConsoleLoggerFactoryProvider;
|
||||
Assert.That(modifiedProvider!.MinLevel, Is.EqualTo(LogLevel.Debug));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ArchitectureProperties可以独立修改
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ArchitectureProperties_Should_Be_Modifiable_Independently()
|
||||
{
|
||||
_configuration!.ArchitectureProperties.AllowLateRegistration = true;
|
||||
_configuration.ArchitectureProperties.StrictPhaseValidation = false;
|
||||
|
||||
Assert.That(_configuration.ArchitectureProperties.AllowLateRegistration,
|
||||
|
||||
Assert.That(_configuration.ArchitectureProperties.AllowLateRegistration,
|
||||
Is.True);
|
||||
Assert.That(_configuration.ArchitectureProperties.StrictPhaseValidation,
|
||||
Assert.That(_configuration.ArchitectureProperties.StrictPhaseValidation,
|
||||
Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ArchitectureConfiguration实现IArchitectureConfiguration接口
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ArchitectureConfiguration_Should_Implement_IArchitectureConfiguration_Interface()
|
||||
{
|
||||
Assert.That(_configuration, Is.InstanceOf<IArchitectureConfiguration>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试新实例不与其他实例共享LoggerProperties
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void New_Instance_Should_Not_Share_LoggerProperties_With_Other_Instance()
|
||||
{
|
||||
var config1 = new ArchitectureConfiguration();
|
||||
var config2 = new ArchitectureConfiguration();
|
||||
|
||||
|
||||
Assert.That(config1.LoggerProperties, Is.Not.SameAs(config2.LoggerProperties));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试新实例不与其他实例共享ArchitectureProperties
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void New_Instance_Should_Not_Share_ArchitectureProperties_With_Other_Instance()
|
||||
{
|
||||
var config1 = new ArchitectureConfiguration();
|
||||
var config2 = new ArchitectureConfiguration();
|
||||
|
||||
Assert.That(config1.ArchitectureProperties,
|
||||
|
||||
Assert.That(config1.ArchitectureProperties,
|
||||
Is.Not.SameAs(config2.ArchitectureProperties));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,8 +3,6 @@ using GFramework.Core.Abstractions.architecture;
|
||||
using GFramework.Core.Abstractions.command;
|
||||
using GFramework.Core.Abstractions.enums;
|
||||
using GFramework.Core.Abstractions.environment;
|
||||
using GFramework.Core.Abstractions.events;
|
||||
using GFramework.Core.Abstractions.ioc;
|
||||
using GFramework.Core.Abstractions.model;
|
||||
using GFramework.Core.Abstractions.query;
|
||||
using GFramework.Core.Abstractions.system;
|
||||
@ -20,30 +18,45 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.architecture;
|
||||
|
||||
/// <summary>
|
||||
/// ArchitectureContext类的单元测试
|
||||
/// 测试内容包括:
|
||||
/// - 构造函数参数验证(所有5个参数)
|
||||
/// - 构造函数空参数异常
|
||||
/// - SendQuery方法 - 正常查询发送
|
||||
/// - SendQuery方法 - 空查询异常
|
||||
/// - SendCommand方法 - 正常命令发送
|
||||
/// - SendCommand方法 - 空命令异常
|
||||
/// - SendCommand_WithResult方法 - 正常命令发送
|
||||
/// - SendCommand_WithResult方法 - 空命令异常
|
||||
/// - SendEvent方法 - 正常事件发送
|
||||
/// - SendEvent_WithInstance方法 - 正常事件发送
|
||||
/// - SendEvent_WithInstance方法 - 空事件异常
|
||||
/// - GetSystem方法 - 获取已注册系统
|
||||
/// - GetSystem方法 - 获取未注册系统
|
||||
/// - GetModel方法 - 获取已注册模型
|
||||
/// - GetModel方法 - 获取未注册模型
|
||||
/// - GetUtility方法 - 获取已注册工具
|
||||
/// - GetUtility方法 - 获取未注册工具
|
||||
/// - GetEnvironment方法 - 获取环境对象
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class ArchitectureContextTests
|
||||
{
|
||||
private ArchitectureContext? _context;
|
||||
private IocContainer? _container;
|
||||
private EventBus? _eventBus;
|
||||
private CommandBus? _commandBus;
|
||||
private QueryBus? _queryBus;
|
||||
private DefaultEnvironment? _environment;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
// 初始化 LoggerFactoryResolver 以支持 IocContainer
|
||||
LoggerFactoryResolver.Provider = new ConsoleLoggerFactoryProvider();
|
||||
|
||||
|
||||
_container = new IocContainer();
|
||||
|
||||
|
||||
// 直接初始化 logger 字段
|
||||
var loggerField = typeof(IocContainer).GetField("_logger",
|
||||
BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
loggerField?.SetValue(_container,
|
||||
LoggerFactoryResolver.Provider.CreateLogger(nameof(ArchitectureContextTests)));
|
||||
|
||||
|
||||
_eventBus = new EventBus();
|
||||
_commandBus = new CommandBus();
|
||||
_queryBus = new QueryBus();
|
||||
@ -51,64 +64,98 @@ public class ArchitectureContextTests
|
||||
_context = new ArchitectureContext(_container, _eventBus, _commandBus, _queryBus, _environment);
|
||||
}
|
||||
|
||||
private ArchitectureContext? _context;
|
||||
private IocContainer? _container;
|
||||
private EventBus? _eventBus;
|
||||
private CommandBus? _commandBus;
|
||||
private QueryBus? _queryBus;
|
||||
private DefaultEnvironment? _environment;
|
||||
|
||||
/// <summary>
|
||||
/// 测试构造函数在所有参数都有效时不应抛出异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Constructor_Should_NotThrow_When_AllParameters_AreValid()
|
||||
{
|
||||
Assert.That(() => new ArchitectureContext(_container!, _eventBus!, _commandBus!, _queryBus!, _environment!),
|
||||
Assert.That(() => new ArchitectureContext(_container!, _eventBus!, _commandBus!, _queryBus!, _environment!),
|
||||
Throws.Nothing);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试构造函数在Container为null时应抛出ArgumentNullException
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Constructor_Should_ThrowArgumentNullException_When_Container_IsNull()
|
||||
{
|
||||
Assert.That(() => new ArchitectureContext(null!, _eventBus!, _commandBus!, _queryBus!, _environment!),
|
||||
Assert.That(() => new ArchitectureContext(null!, _eventBus!, _commandBus!, _queryBus!, _environment!),
|
||||
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("container"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试构造函数在EventBus为null时应抛出ArgumentNullException
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Constructor_Should_ThrowArgumentNullException_When_EventBus_IsNull()
|
||||
{
|
||||
Assert.That(() => new ArchitectureContext(_container!, null!, _commandBus!, _queryBus!, _environment!),
|
||||
Assert.That(() => new ArchitectureContext(_container!, null!, _commandBus!, _queryBus!, _environment!),
|
||||
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("eventBus"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试构造函数在CommandBus为null时应抛出ArgumentNullException
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Constructor_Should_ThrowArgumentNullException_When_CommandBus_IsNull()
|
||||
{
|
||||
Assert.That(() => new ArchitectureContext(_container!, _eventBus!, null!, _queryBus!, _environment!),
|
||||
Assert.That(() => new ArchitectureContext(_container!, _eventBus!, null!, _queryBus!, _environment!),
|
||||
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("commandBus"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试构造函数在QueryBus为null时应抛出ArgumentNullException
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Constructor_Should_ThrowArgumentNullException_When_QueryBus_IsNull()
|
||||
{
|
||||
Assert.That(() => new ArchitectureContext(_container!, _eventBus!, _commandBus!, null!, _environment!),
|
||||
Assert.That(() => new ArchitectureContext(_container!, _eventBus!, _commandBus!, null!, _environment!),
|
||||
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("queryBus"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试构造函数在Environment为null时应抛出ArgumentNullException
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Constructor_Should_ThrowArgumentNullException_When_Environment_IsNull()
|
||||
{
|
||||
Assert.That(() => new ArchitectureContext(_container!, _eventBus!, _commandBus!, _queryBus!, null!),
|
||||
Assert.That(() => new ArchitectureContext(_container!, _eventBus!, _commandBus!, _queryBus!, null!),
|
||||
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("environment"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试SendQuery方法在查询有效时返回正确结果
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SendQuery_Should_ReturnResult_When_Query_IsValid()
|
||||
{
|
||||
var testQuery = new TestQueryV2 { Result = 42 };
|
||||
var result = _context!.SendQuery(testQuery);
|
||||
|
||||
|
||||
Assert.That(result, Is.EqualTo(42));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试SendQuery方法在查询为null时应抛出ArgumentNullException
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SendQuery_Should_ThrowArgumentNullException_When_Query_IsNull()
|
||||
{
|
||||
Assert.That(() => _context!.SendQuery<int>(null!),
|
||||
Assert.That(() => _context!.SendQuery<int>(null!),
|
||||
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("query"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试SendCommand方法在命令有效时正确执行
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SendCommand_Should_ExecuteCommand_When_Command_IsValid()
|
||||
{
|
||||
@ -117,39 +164,54 @@ public class ArchitectureContextTests
|
||||
Assert.That(testCommand.Executed, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试SendCommand方法在命令为null时应抛出ArgumentNullException
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SendCommand_Should_ThrowArgumentNullException_When_Command_IsNull()
|
||||
{
|
||||
Assert.That(() => _context!.SendCommand((ICommand)null!),
|
||||
Assert.That(() => _context!.SendCommand((ICommand)null!),
|
||||
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("command"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试SendCommand方法(带返回值)在命令有效时返回正确结果
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SendCommand_WithResult_Should_ReturnResult_When_Command_IsValid()
|
||||
{
|
||||
var testCommand = new TestCommandWithResultV2 { Result = 123 };
|
||||
var result = _context!.SendCommand(testCommand);
|
||||
|
||||
|
||||
Assert.That(result, Is.EqualTo(123));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试SendCommand方法(带返回值)在命令为null时应抛出ArgumentNullException
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SendCommand_WithResult_Should_ThrowArgumentNullException_When_Command_IsNull()
|
||||
{
|
||||
Assert.That(() => _context!.SendCommand((ICommand<int>)null!),
|
||||
Assert.That(() => _context!.SendCommand((ICommand<int>)null!),
|
||||
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("command"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试SendEvent方法在事件类型有效时正确发送事件
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SendEvent_Should_SendEvent_When_EventType_IsValid()
|
||||
{
|
||||
bool eventReceived = false;
|
||||
_context!.RegisterEvent<TestEventV2>(_ => eventReceived = true);
|
||||
_context.SendEvent<TestEventV2>();
|
||||
|
||||
|
||||
Assert.That(eventReceived, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试SendEvent方法(带实例)在事件实例有效时正确发送事件
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SendEvent_WithInstance_Should_SendEvent_When_EventInstance_IsValid()
|
||||
{
|
||||
@ -157,82 +219,106 @@ public class ArchitectureContextTests
|
||||
var testEvent = new TestEventV2();
|
||||
_context!.RegisterEvent<TestEventV2>(_ => eventReceived = true);
|
||||
_context.SendEvent(testEvent);
|
||||
|
||||
|
||||
Assert.That(eventReceived, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试SendEvent方法(带实例)在事件实例为null时应抛出ArgumentNullException
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SendEvent_WithInstance_Should_ThrowArgumentNullException_When_EventInstance_IsNull()
|
||||
{
|
||||
Assert.That(() => _context!.SendEvent<TestEventV2>(null!),
|
||||
Assert.That(() => _context!.SendEvent<TestEventV2>(null!),
|
||||
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("e"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetSystem方法在系统已注册时返回注册的系统
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetSystem_Should_ReturnRegisteredSystem_When_SystemIsRegistered()
|
||||
{
|
||||
var testSystem = new TestSystemV2();
|
||||
_container!.RegisterPlurality(testSystem);
|
||||
|
||||
|
||||
var result = _context!.GetSystem<TestSystemV2>();
|
||||
|
||||
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.That(result, Is.SameAs(testSystem));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetSystem方法在系统未注册时返回null
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetSystem_Should_ReturnNull_When_SystemIsNotRegistered()
|
||||
{
|
||||
var result = _context!.GetSystem<TestSystemV2>();
|
||||
|
||||
|
||||
Assert.That(result, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetModel方法在模型已注册时返回注册的模型
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetModel_Should_ReturnRegisteredModel_When_ModelIsRegistered()
|
||||
{
|
||||
var testModel = new TestModelV2();
|
||||
_container!.RegisterPlurality(testModel);
|
||||
|
||||
|
||||
var result = _context!.GetModel<TestModelV2>();
|
||||
|
||||
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.That(result, Is.SameAs(testModel));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetModel方法在模型未注册时返回null
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetModel_Should_ReturnNull_When_ModelIsNotRegistered()
|
||||
{
|
||||
var result = _context!.GetModel<TestModelV2>();
|
||||
|
||||
|
||||
Assert.That(result, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetUtility方法在工具已注册时返回注册的工具
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetUtility_Should_ReturnRegisteredUtility_When_UtilityIsRegistered()
|
||||
{
|
||||
var testUtility = new TestUtilityV2();
|
||||
_container!.RegisterPlurality(testUtility);
|
||||
|
||||
|
||||
var result = _context!.GetUtility<TestUtilityV2>();
|
||||
|
||||
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.That(result, Is.SameAs(testUtility));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetUtility方法在工具未注册时返回null
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetUtility_Should_ReturnNull_When_UtilityIsNotRegistered()
|
||||
{
|
||||
var result = _context!.GetUtility<TestUtilityV2>();
|
||||
|
||||
|
||||
Assert.That(result, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetEnvironment方法返回环境实例
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetEnvironment_Should_Return_EnvironmentInstance()
|
||||
{
|
||||
var environment = _context!.GetEnvironment();
|
||||
|
||||
|
||||
Assert.That(environment, Is.Not.Null);
|
||||
Assert.That(environment, Is.InstanceOf<IEnvironment>());
|
||||
}
|
||||
@ -244,42 +330,66 @@ public class TestSystemV2 : ISystem
|
||||
{
|
||||
private IArchitectureContext _context = null!;
|
||||
public int Id { get; init; }
|
||||
|
||||
|
||||
public void SetContext(IArchitectureContext context) => _context = context;
|
||||
public IArchitectureContext GetContext() => _context;
|
||||
public void Init() { }
|
||||
public void Destroy() { }
|
||||
public void OnArchitecturePhase(ArchitecturePhase phase) { }
|
||||
|
||||
public void Init()
|
||||
{
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnArchitecturePhase(ArchitecturePhase phase)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class TestModelV2 : IModel
|
||||
{
|
||||
private IArchitectureContext _context = null!;
|
||||
public int Id { get; init; }
|
||||
|
||||
|
||||
public void SetContext(IArchitectureContext context) => _context = context;
|
||||
public IArchitectureContext GetContext() => _context;
|
||||
public void Init() { }
|
||||
public void Destroy() { }
|
||||
public void OnArchitecturePhase(ArchitecturePhase phase) { }
|
||||
|
||||
public void Init()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnArchitecturePhase(ArchitecturePhase phase)
|
||||
{
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class TestUtilityV2 : IUtility
|
||||
{
|
||||
private IArchitectureContext _context = null!;
|
||||
public int Id { get; init; }
|
||||
|
||||
|
||||
public void SetContext(IArchitectureContext context) => _context = context;
|
||||
public IArchitectureContext GetContext() => _context;
|
||||
public void Init() { }
|
||||
public void Destroy() { }
|
||||
|
||||
public void Init()
|
||||
{
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class TestQueryV2 : IQuery<int>
|
||||
{
|
||||
private IArchitectureContext _context = null!;
|
||||
public int Result { get; init; }
|
||||
|
||||
|
||||
public int Do() => Result;
|
||||
public void SetContext(IArchitectureContext context) => _context = context;
|
||||
public IArchitectureContext GetContext() => _context;
|
||||
@ -289,7 +399,7 @@ public class TestCommandV2 : ICommand
|
||||
{
|
||||
private IArchitectureContext _context = null!;
|
||||
public bool Executed { get; private set; }
|
||||
|
||||
|
||||
public void Execute() => Executed = true;
|
||||
public void SetContext(IArchitectureContext context) => _context = context;
|
||||
public IArchitectureContext GetContext() => _context;
|
||||
@ -299,7 +409,7 @@ public class TestCommandWithResultV2 : ICommand<int>
|
||||
{
|
||||
private IArchitectureContext _context = null!;
|
||||
public int Result { get; init; }
|
||||
|
||||
|
||||
public int Execute() => Result;
|
||||
public void SetContext(IArchitectureContext context) => _context = context;
|
||||
public IArchitectureContext GetContext() => _context;
|
||||
@ -310,4 +420,4 @@ public class TestEventV2
|
||||
public int Data { get; init; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using GFramework.Core.Abstractions.architecture;
|
||||
using GFramework.Core.Abstractions.command;
|
||||
using GFramework.Core.Abstractions.environment;
|
||||
@ -18,12 +17,22 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.architecture;
|
||||
|
||||
/// <summary>
|
||||
/// ArchitectureServices类的单元测试
|
||||
/// 测试内容包括:
|
||||
/// - 服务容器初始化
|
||||
/// - 所有服务实例创建(Container, EventBus, CommandBus, QueryBus)
|
||||
/// - SetContext方法 - 设置上下文
|
||||
/// - SetContext方法 - 重复设置上下文
|
||||
/// - GetContext方法 - 获取已设置上下文
|
||||
/// - GetContext方法 - 未设置上下文时返回null
|
||||
/// - 上下文传播到容器
|
||||
/// - IArchitectureServices接口实现验证
|
||||
/// - 服务独立性验证(多个实例)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class ArchitectureServicesTests
|
||||
{
|
||||
private ArchitectureServices? _services;
|
||||
private TestArchitectureContextV3? _context;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@ -31,6 +40,12 @@ public class ArchitectureServicesTests
|
||||
_context = new TestArchitectureContextV3();
|
||||
}
|
||||
|
||||
private ArchitectureServices? _services;
|
||||
private TestArchitectureContextV3? _context;
|
||||
|
||||
/// <summary>
|
||||
/// 测试构造函数初始化所有服务
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Constructor_Should_Initialize_AllServices()
|
||||
{
|
||||
@ -47,6 +62,9 @@ public class ArchitectureServicesTests
|
||||
Assert.That(_services.Container, Is.InstanceOf<IocContainer>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试EventBus是EventBus的实例
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void EventBus_Should_Be_Instance_Of_EventBus()
|
||||
{
|
||||
@ -54,6 +72,9 @@ public class ArchitectureServicesTests
|
||||
Assert.That(_services.EventBus, Is.InstanceOf<EventBus>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试CommandBus是CommandBus的实例
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void CommandBus_Should_Be_Instance_Of_CommandBus()
|
||||
{
|
||||
@ -61,6 +82,9 @@ public class ArchitectureServicesTests
|
||||
Assert.That(_services.CommandBus, Is.InstanceOf<CommandBus>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试QueryBus是QueryBus的实例
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void QueryBus_Should_Be_Instance_Of_QueryBus()
|
||||
{
|
||||
@ -68,94 +92,124 @@ public class ArchitectureServicesTests
|
||||
Assert.That(_services.QueryBus, Is.InstanceOf<QueryBus>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试SetContext设置内部Context字段
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SetContext_Should_Set_Context_Internal_Field()
|
||||
{
|
||||
_services!.SetContext(_context!);
|
||||
|
||||
|
||||
var context = _services.GetContext();
|
||||
Assert.That(context, Is.SameAs(_context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试SetContext将上下文传播到Container
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SetContext_Should_Propagate_Context_To_Container()
|
||||
{
|
||||
_services!.SetContext(_context!);
|
||||
|
||||
|
||||
var containerContext = _services.Container.GetContext();
|
||||
Assert.That(containerContext, Is.SameAs(_context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetContext在SetContext后返回上下文
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetContext_Should_Return_Context_After_SetContext()
|
||||
{
|
||||
_services!.SetContext(_context!);
|
||||
|
||||
|
||||
var context = _services.GetContext();
|
||||
Assert.That(context, Is.Not.Null);
|
||||
Assert.That(context, Is.SameAs(_context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetContext在未设置上下文时返回null
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetContext_Should_ReturnNull_When_Context_Not_Set()
|
||||
{
|
||||
var context = _services!.GetContext();
|
||||
|
||||
|
||||
Assert.That(context, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试SetContext替换已存在的上下文
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SetContext_Should_Replace_Existing_Context()
|
||||
{
|
||||
var context1 = new TestArchitectureContextV3 { Id = 1 };
|
||||
var context2 = new TestArchitectureContextV3 { Id = 2 };
|
||||
|
||||
|
||||
_services!.SetContext(context1);
|
||||
_services.SetContext(context2);
|
||||
|
||||
|
||||
var context = _services.GetContext();
|
||||
Assert.That(context, Is.SameAs(context2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ArchitectureServices实现IArchitectureServices接口
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ArchitectureServices_Should_Implement_IArchitectureServices_Interface()
|
||||
{
|
||||
Assert.That(_services, Is.InstanceOf<IArchitectureServices>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试多个实例有独立的Container
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Multiple_Instances_Should_Have_Independent_Container()
|
||||
{
|
||||
var services1 = new ArchitectureServices();
|
||||
var services2 = new ArchitectureServices();
|
||||
|
||||
|
||||
Assert.That(services1.Container, Is.Not.SameAs(services2.Container));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试多个实例有独立的EventBus
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Multiple_Instances_Should_Have_Independent_EventBus()
|
||||
{
|
||||
var services1 = new ArchitectureServices();
|
||||
var services2 = new ArchitectureServices();
|
||||
|
||||
|
||||
Assert.That(services1.EventBus, Is.Not.SameAs(services2.EventBus));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试多个实例有独立的CommandBus
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Multiple_Instances_Should_Have_Independent_CommandBus()
|
||||
{
|
||||
var services1 = new ArchitectureServices();
|
||||
var services2 = new ArchitectureServices();
|
||||
|
||||
|
||||
Assert.That(services1.CommandBus, Is.Not.SameAs(services2.CommandBus));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试多个实例有独立的QueryBus
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Multiple_Instances_Should_Have_Independent_QueryBus()
|
||||
{
|
||||
var services1 = new ArchitectureServices();
|
||||
var services2 = new ArchitectureServices();
|
||||
|
||||
|
||||
Assert.That(services1.QueryBus, Is.Not.SameAs(services2.QueryBus));
|
||||
}
|
||||
}
|
||||
@ -167,12 +221,12 @@ public class TestArchitectureContextV3 : IArchitectureContext
|
||||
private readonly IocContainer _container = new();
|
||||
private readonly DefaultEnvironment _environment = new();
|
||||
public int Id { get; init; }
|
||||
|
||||
|
||||
public IIocContainer Container => _container;
|
||||
public IEventBus EventBus => new EventBus();
|
||||
public ICommandBus CommandBus => new CommandBus();
|
||||
public IQueryBus QueryBus => new QueryBus();
|
||||
|
||||
|
||||
public TModel? GetModel<TModel>() where TModel : class, IModel => _container.Get<TModel>();
|
||||
public TSystem? GetSystem<TSystem>() where TSystem : class, ISystem => _container.Get<TSystem>();
|
||||
public TUtility? GetUtility<TUtility>() where TUtility : class, IUtility => _container.Get<TUtility>();
|
||||
@ -200,4 +254,4 @@ public class TestArchitectureContextV3 : IArchitectureContext
|
||||
public IEnvironment GetEnvironment() => _environment;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
@ -17,21 +17,46 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.architecture;
|
||||
|
||||
/// <summary>
|
||||
/// GameContext类的单元测试
|
||||
/// 测试内容包括:
|
||||
/// - ArchitectureReadOnlyDictionary在启动时为空
|
||||
/// - Bind方法添加上下文到字典
|
||||
/// - Bind重复类型时抛出异常
|
||||
/// - GetByType返回正确的上下文
|
||||
/// - GetByType未找到时抛出异常
|
||||
/// - Get泛型方法返回正确的上下文
|
||||
/// - TryGet方法在找到时返回true
|
||||
/// - TryGet方法在未找到时返回false
|
||||
/// - GetFirstArchitectureContext在存在时返回
|
||||
/// - GetFirstArchitectureContext为空时抛出异常
|
||||
/// - Unbind移除上下文
|
||||
/// - Clear移除所有上下文
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class GameContextTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试初始化方法,在每个测试方法执行前清空GameContext
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
GameContext.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试清理方法,在每个测试方法执行后清空GameContext
|
||||
/// </summary>
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameContext.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ArchitectureReadOnlyDictionary在启动时返回空字典
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ArchitectureReadOnlyDictionary_Should_Return_Empty_At_Start()
|
||||
{
|
||||
@ -40,6 +65,9 @@ public class GameContextTests
|
||||
Assert.That(dict.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试Bind方法是否正确将上下文添加到字典中
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Bind_Should_Add_Context_To_Dictionary()
|
||||
{
|
||||
@ -50,6 +78,9 @@ public class GameContextTests
|
||||
Assert.That(GameContext.ArchitectureReadOnlyDictionary.Count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试Bind方法在绑定重复类型时是否抛出InvalidOperationException异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Bind_WithDuplicateType_Should_ThrowInvalidOperationException()
|
||||
{
|
||||
@ -62,6 +93,9 @@ public class GameContextTests
|
||||
GameContext.Bind(typeof(TestArchitecture), context2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetByType方法是否返回正确的上下文
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetByType_Should_Return_Correct_Context()
|
||||
{
|
||||
@ -73,6 +107,9 @@ public class GameContextTests
|
||||
Assert.That(result, Is.SameAs(context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetByType方法在未找到对应类型时是否抛出InvalidOperationException异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetByType_Should_Throw_When_Not_Found()
|
||||
{
|
||||
@ -80,6 +117,9 @@ public class GameContextTests
|
||||
GameContext.GetByType(typeof(TestArchitecture)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试Get泛型方法是否返回正确的上下文
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetGeneric_Should_Return_Correct_Context()
|
||||
{
|
||||
@ -91,6 +131,9 @@ public class GameContextTests
|
||||
Assert.That(result, Is.SameAs(context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试TryGet方法在找到上下文时是否返回true并正确设置输出参数
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TryGet_Should_ReturnTrue_When_Found()
|
||||
{
|
||||
@ -103,6 +146,9 @@ public class GameContextTests
|
||||
Assert.That(foundContext, Is.SameAs(context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试TryGet方法在未找到上下文时是否返回false且输出参数为null
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TryGet_Should_ReturnFalse_When_Not_Found()
|
||||
{
|
||||
@ -112,6 +158,9 @@ public class GameContextTests
|
||||
Assert.That(foundContext, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetFirstArchitectureContext方法在存在上下文时是否返回正确的上下文
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetFirstArchitectureContext_Should_Return_When_Exists()
|
||||
{
|
||||
@ -123,6 +172,9 @@ public class GameContextTests
|
||||
Assert.That(result, Is.SameAs(context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetFirstArchitectureContext方法在没有上下文时是否抛出InvalidOperationException异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetFirstArchitectureContext_Should_Throw_When_Empty()
|
||||
{
|
||||
@ -130,6 +182,9 @@ public class GameContextTests
|
||||
GameContext.GetFirstArchitectureContext());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试Unbind方法是否正确移除指定类型的上下文
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Unbind_Should_Remove_Context()
|
||||
{
|
||||
@ -141,6 +196,9 @@ public class GameContextTests
|
||||
Assert.That(GameContext.ArchitectureReadOnlyDictionary.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试Clear方法是否正确移除所有上下文
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Clear_Should_Remove_All_Contexts()
|
||||
{
|
||||
@ -153,46 +211,133 @@ public class GameContextTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用的架构类,继承自Architecture
|
||||
/// </summary>
|
||||
public class TestArchitecture : Architecture
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化方法,当前为空实现
|
||||
/// </summary>
|
||||
protected override void Init()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用的架构上下文类,实现了IArchitectureContext接口
|
||||
/// </summary>
|
||||
public class TestArchitectureContext : IArchitectureContext
|
||||
{
|
||||
private readonly IocContainer _container = new();
|
||||
|
||||
/// <summary>
|
||||
/// 获取依赖注入容器
|
||||
/// </summary>
|
||||
public IIocContainer Container => _container;
|
||||
|
||||
/// <summary>
|
||||
/// 获取事件总线
|
||||
/// </summary>
|
||||
public IEventBus EventBus => new EventBus();
|
||||
|
||||
/// <summary>
|
||||
/// 获取命令总线
|
||||
/// </summary>
|
||||
public ICommandBus CommandBus => new CommandBus();
|
||||
|
||||
/// <summary>
|
||||
/// 获取查询总线
|
||||
/// </summary>
|
||||
public IQueryBus QueryBus => new QueryBus();
|
||||
|
||||
/// <summary>
|
||||
/// 获取环境对象
|
||||
/// </summary>
|
||||
public IEnvironment Environment => new DefaultEnvironment();
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的模型
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">模型类型</typeparam>
|
||||
/// <returns>模型实例或null</returns>
|
||||
public TModel? GetModel<TModel>() where TModel : class, IModel => _container.Get<TModel>();
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的系统
|
||||
/// </summary>
|
||||
/// <typeparam name="TSystem">系统类型</typeparam>
|
||||
/// <returns>系统实例或null</returns>
|
||||
public TSystem? GetSystem<TSystem>() where TSystem : class, ISystem => _container.Get<TSystem>();
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的工具
|
||||
/// </summary>
|
||||
/// <typeparam name="TUtility">工具类型</typeparam>
|
||||
/// <returns>工具实例或null</returns>
|
||||
public TUtility? GetUtility<TUtility>() where TUtility : class, IUtility => _container.Get<TUtility>();
|
||||
|
||||
/// <summary>
|
||||
/// 发送事件
|
||||
/// </summary>
|
||||
/// <typeparam name="TEvent">事件类型</typeparam>
|
||||
public void SendEvent<TEvent>() where TEvent : new()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送事件
|
||||
/// </summary>
|
||||
/// <typeparam name="TEvent">事件类型</typeparam>
|
||||
/// <param name="e">事件实例</param>
|
||||
public void SendEvent<TEvent>(TEvent e) where TEvent : class
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册事件处理器
|
||||
/// </summary>
|
||||
/// <typeparam name="TEvent">事件类型</typeparam>
|
||||
/// <param name="handler">事件处理委托</param>
|
||||
/// <returns>取消注册接口</returns>
|
||||
public IUnRegister RegisterEvent<TEvent>(Action<TEvent> handler) => new DefaultUnRegister(() => { });
|
||||
|
||||
/// <summary>
|
||||
/// 取消注册事件处理器
|
||||
/// </summary>
|
||||
/// <typeparam name="TEvent">事件类型</typeparam>
|
||||
/// <param name="onEvent">事件处理委托</param>
|
||||
public void UnRegisterEvent<TEvent>(Action<TEvent> onEvent)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送命令
|
||||
/// </summary>
|
||||
/// <param name="command">命令对象</param>
|
||||
public void SendCommand(ICommand command)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送带返回值的命令
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">返回值类型</typeparam>
|
||||
/// <param name="command">命令对象</param>
|
||||
/// <returns>命令执行结果</returns>
|
||||
public TResult SendCommand<TResult>(ICommand<TResult> command) => default!;
|
||||
|
||||
/// <summary>
|
||||
/// 发送查询请求
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">查询结果类型</typeparam>
|
||||
/// <param name="query">查询对象</param>
|
||||
/// <returns>查询结果</returns>
|
||||
public TResult SendQuery<TResult>(IQuery<TResult> query) => default!;
|
||||
|
||||
/// <summary>
|
||||
/// 获取环境对象
|
||||
/// </summary>
|
||||
/// <returns>环境对象</returns>
|
||||
public IEnvironment GetEnvironment() => Environment;
|
||||
}
|
||||
@ -4,6 +4,14 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.command;
|
||||
|
||||
/// <summary>
|
||||
/// CommandBus类的单元测试
|
||||
/// 测试内容包括:
|
||||
/// - Send方法执行命令
|
||||
/// - Send方法处理null命令
|
||||
/// - Send方法(带返回值)返回值
|
||||
/// - Send方法(带返回值)处理null命令
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class CommandBusTests
|
||||
{
|
||||
@ -15,6 +23,9 @@ public class CommandBusTests
|
||||
|
||||
private CommandBus _commandBus = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 测试Send方法执行命令
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Send_Should_Execute_Command()
|
||||
{
|
||||
@ -26,12 +37,18 @@ public class CommandBusTests
|
||||
Assert.That(command.ExecutedValue, Is.EqualTo(42));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试Send方法处理null命令时抛出ArgumentNullException异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Send_WithNullCommand_Should_ThrowArgumentNullException()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => _commandBus.Send(null!));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试Send方法(带返回值)正确返回值
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Send_WithResult_Should_Return_Value()
|
||||
{
|
||||
@ -44,6 +61,9 @@ public class CommandBusTests
|
||||
Assert.That(result, Is.EqualTo(200));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试Send方法(带返回值)处理null命令时抛出ArgumentNullException异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Send_WithResult_AndNullCommand_Should_ThrowArgumentNullException()
|
||||
{
|
||||
@ -51,20 +71,44 @@ public class CommandBusTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用命令输入类,实现ICommandInput接口
|
||||
/// </summary>
|
||||
public sealed class TestCommandInput : ICommandInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置值
|
||||
/// </summary>
|
||||
public int Value { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用命令类,继承AbstractCommand
|
||||
/// </summary>
|
||||
public sealed class TestCommand : AbstractCommand<TestCommandInput>
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="input">命令输入</param>
|
||||
public TestCommand(TestCommandInput input) : base(input)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取命令是否已执行
|
||||
/// </summary>
|
||||
public bool Executed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取执行的值
|
||||
/// </summary>
|
||||
public int ExecutedValue { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 执行命令的重写方法
|
||||
/// </summary>
|
||||
/// <param name="input">命令输入</param>
|
||||
protected override void OnExecute(TestCommandInput input)
|
||||
{
|
||||
Executed = true;
|
||||
@ -72,14 +116,29 @@ public sealed class TestCommand : AbstractCommand<TestCommandInput>
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用带返回值的命令类,继承AbstractCommand
|
||||
/// </summary>
|
||||
public sealed class TestCommandWithResult : AbstractCommand<TestCommandInput, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="input">命令输入</param>
|
||||
public TestCommandWithResult(TestCommandInput input) : base(input)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取命令是否已执行
|
||||
/// </summary>
|
||||
public bool Executed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 执行命令并返回结果的重写方法
|
||||
/// </summary>
|
||||
/// <param name="input">命令输入</param>
|
||||
/// <returns>执行结果</returns>
|
||||
protected override int OnExecute(TestCommandInput input)
|
||||
{
|
||||
Executed = true;
|
||||
|
||||
@ -4,9 +4,15 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.environment;
|
||||
|
||||
/// <summary>
|
||||
/// 测试环境相关的单元测试类,用于验证环境管理功能的正确性
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class EnvironmentTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 在每个测试方法执行前进行初始化设置
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@ -16,6 +22,9 @@ public class EnvironmentTests
|
||||
|
||||
private TestEnvironment _environment = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 验证默认环境的名称是否正确返回"Default"
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void DefaultEnvironment_Name_Should_ReturnDefault()
|
||||
{
|
||||
@ -24,6 +33,9 @@ public class EnvironmentTests
|
||||
Assert.That(env.Name, Is.EqualTo("Default"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证默认环境的初始化方法不会抛出异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void DefaultEnvironment_Initialize_Should_NotThrow()
|
||||
{
|
||||
@ -32,6 +44,9 @@ public class EnvironmentTests
|
||||
Assert.DoesNotThrow(() => env.Initialize());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当键存在时Get方法应该返回正确的值
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Get_Should_Return_Value_When_Key_Exists()
|
||||
{
|
||||
@ -42,6 +57,9 @@ public class EnvironmentTests
|
||||
Assert.That(result, Is.EqualTo("testValue"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当键不存在时Get方法应该返回null
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Get_Should_ReturnNull_When_Key_Not_Exists()
|
||||
{
|
||||
@ -50,6 +68,9 @@ public class EnvironmentTests
|
||||
Assert.That(result, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当类型不匹配时Get方法应该返回null
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Get_Should_ReturnNull_When_Type_Does_Not_Match()
|
||||
{
|
||||
@ -60,6 +81,9 @@ public class EnvironmentTests
|
||||
Assert.That(result, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当键存在时TryGet方法应该返回true并输出正确的值
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TryGet_Should_ReturnTrue_And_Value_When_Key_Exists()
|
||||
{
|
||||
@ -71,6 +95,9 @@ public class EnvironmentTests
|
||||
Assert.That(value, Is.EqualTo("testValue"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当键不存在时TryGet方法应该返回false且输出值为null
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TryGet_Should_ReturnFalse_When_Key_Not_Exists()
|
||||
{
|
||||
@ -80,6 +107,9 @@ public class EnvironmentTests
|
||||
Assert.That(value, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当类型不匹配时TryGet方法应该返回false且输出值为null
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TryGet_Should_ReturnFalse_When_Type_Does_Not_Match()
|
||||
{
|
||||
@ -91,6 +121,9 @@ public class EnvironmentTests
|
||||
Assert.That(value, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当键存在时GetRequired方法应该返回正确的值
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetRequired_Should_Return_Value_When_Key_Exists()
|
||||
{
|
||||
@ -101,6 +134,9 @@ public class EnvironmentTests
|
||||
Assert.That(result, Is.EqualTo("testValue"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当键不存在时GetRequired方法应该抛出InvalidOperationException异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetRequired_Should_ThrowInvalidOperationException_When_Key_Not_Exists()
|
||||
{
|
||||
@ -108,6 +144,9 @@ public class EnvironmentTests
|
||||
_environment.GetRequired<string>("nonExistentKey"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Register方法应该将值添加到字典中
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Register_Should_Add_Value_To_Dictionary()
|
||||
{
|
||||
@ -118,6 +157,9 @@ public class EnvironmentTests
|
||||
Assert.That(result, Is.EqualTo("newValue"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Register方法应该覆盖已存在的值
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Register_Should_Overwrite_Existing_Value()
|
||||
{
|
||||
@ -129,6 +171,9 @@ public class EnvironmentTests
|
||||
Assert.That(result, Is.EqualTo("value2"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证通过IEnvironment接口的Register方法应该能够添加值
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IEnvironment_Register_Should_Add_Value()
|
||||
{
|
||||
@ -141,15 +186,29 @@ public class EnvironmentTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试环境实现类,继承自EnvironmentBase
|
||||
/// </summary>
|
||||
public class TestEnvironment : EnvironmentBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取环境名称
|
||||
/// </summary>
|
||||
public override string Name { get; } = "TestEnvironment";
|
||||
|
||||
/// <summary>
|
||||
/// 注册键值对到环境中
|
||||
/// </summary>
|
||||
/// <param name="key">要注册的键</param>
|
||||
/// <param name="value">要注册的值</param>
|
||||
public new void Register(string key, object value)
|
||||
{
|
||||
base.Register(key, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化环境
|
||||
/// </summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
@ -1,137 +1,173 @@
|
||||
using System;
|
||||
using GFramework.Core.events;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.events;
|
||||
|
||||
/// <summary>
|
||||
/// ArchitectureEvents类的单元测试
|
||||
/// 测试内容包括:
|
||||
/// - ArchitectureLifecycleReadyEvent事件触发
|
||||
/// - ArchitectureDestroyingEvent事件触发
|
||||
/// - ArchitectureDestroyedEvent事件触发
|
||||
/// - ArchitectureFailedInitializationEvent事件触发
|
||||
/// - 事件的参数传递
|
||||
/// - 事件的订阅和取消订阅
|
||||
/// - 事件顺序验证(LifecycleReady -> Destroying -> Destroyed)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class ArchitectureEventsTests
|
||||
{
|
||||
private EventBus? _eventBus;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_eventBus = new EventBus();
|
||||
}
|
||||
|
||||
private EventBus? _eventBus;
|
||||
|
||||
/// <summary>
|
||||
/// 测试ArchitectureLifecycleReadyEvent事件可以创建并发送
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ArchitectureLifecycleReadyEvent_Should_Be_Created_And_Sent()
|
||||
{
|
||||
bool eventReceived = false;
|
||||
|
||||
|
||||
_eventBus!.Register<ArchitectureEvents.ArchitectureLifecycleReadyEvent>(_ => eventReceived = true);
|
||||
_eventBus.Send<ArchitectureEvents.ArchitectureLifecycleReadyEvent>();
|
||||
|
||||
|
||||
Assert.That(eventReceived, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ArchitectureDestroyingEvent事件可以创建并发送
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ArchitectureDestroyingEvent_Should_Be_Created_And_Sent()
|
||||
{
|
||||
bool eventReceived = false;
|
||||
|
||||
|
||||
_eventBus!.Register<ArchitectureEvents.ArchitectureDestroyingEvent>(_ => eventReceived = true);
|
||||
_eventBus.Send<ArchitectureEvents.ArchitectureDestroyingEvent>();
|
||||
|
||||
|
||||
Assert.That(eventReceived, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ArchitectureDestroyedEvent事件可以创建并发送
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ArchitectureDestroyedEvent_Should_Be_Created_And_Sent()
|
||||
{
|
||||
bool eventReceived = false;
|
||||
|
||||
|
||||
_eventBus!.Register<ArchitectureEvents.ArchitectureDestroyedEvent>(_ => eventReceived = true);
|
||||
_eventBus.Send<ArchitectureEvents.ArchitectureDestroyedEvent>();
|
||||
|
||||
|
||||
Assert.That(eventReceived, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ArchitectureFailedInitializationEvent事件可以创建并发送
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ArchitectureFailedInitializationEvent_Should_Be_Created_And_Sent()
|
||||
{
|
||||
bool eventReceived = false;
|
||||
|
||||
|
||||
_eventBus!.Register<ArchitectureEvents.ArchitectureFailedInitializationEvent>(_ => eventReceived = true);
|
||||
_eventBus.Send<ArchitectureEvents.ArchitectureFailedInitializationEvent>();
|
||||
|
||||
|
||||
Assert.That(eventReceived, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试事件按正确顺序发送
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Events_Should_Be_Sent_In_Correct_Order()
|
||||
{
|
||||
var events = new List<string>();
|
||||
|
||||
|
||||
_eventBus!.Register<ArchitectureEvents.ArchitectureLifecycleReadyEvent>(_ => events.Add("Ready"));
|
||||
_eventBus!.Register<ArchitectureEvents.ArchitectureDestroyingEvent>(_ => events.Add("Destroying"));
|
||||
_eventBus!.Register<ArchitectureEvents.ArchitectureDestroyedEvent>(_ => events.Add("Destroyed"));
|
||||
|
||||
|
||||
_eventBus.Send<ArchitectureEvents.ArchitectureLifecycleReadyEvent>();
|
||||
_eventBus.Send<ArchitectureEvents.ArchitectureDestroyingEvent>();
|
||||
_eventBus.Send<ArchitectureEvents.ArchitectureDestroyedEvent>();
|
||||
|
||||
|
||||
Assert.That(events.Count, Is.EqualTo(3));
|
||||
Assert.That(events[0], Is.EqualTo("Ready"));
|
||||
Assert.That(events[1], Is.EqualTo("Destroying"));
|
||||
Assert.That(events[2], Is.EqualTo("Destroyed"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试多个订阅者都能接收到事件
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Multiple_Subscribers_Should_All_Receive_Events()
|
||||
{
|
||||
var count1 = 0;
|
||||
var count2 = 0;
|
||||
|
||||
|
||||
_eventBus!.Register<ArchitectureEvents.ArchitectureLifecycleReadyEvent>(_ => count1++);
|
||||
_eventBus!.Register<ArchitectureEvents.ArchitectureLifecycleReadyEvent>(_ => count2++);
|
||||
|
||||
|
||||
_eventBus.Send<ArchitectureEvents.ArchitectureLifecycleReadyEvent>();
|
||||
|
||||
|
||||
Assert.That(count1, Is.EqualTo(1));
|
||||
Assert.That(count2, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试事件取消订阅后不再接收未来事件
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Event_UnRegister_Should_Prevent_Future_Events()
|
||||
{
|
||||
var count = 0;
|
||||
var unregister = _eventBus!.Register<ArchitectureEvents.ArchitectureLifecycleReadyEvent>(_ => count++);
|
||||
|
||||
|
||||
_eventBus.Send<ArchitectureEvents.ArchitectureLifecycleReadyEvent>();
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
|
||||
|
||||
unregister.UnRegister();
|
||||
_eventBus.Send<ArchitectureEvents.ArchitectureLifecycleReadyEvent>();
|
||||
|
||||
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试不同类型事件互不干扰
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Different_Events_Should_Not_Interfere()
|
||||
{
|
||||
bool readyReceived = false;
|
||||
bool destroyingReceived = false;
|
||||
|
||||
|
||||
_eventBus!.Register<ArchitectureEvents.ArchitectureLifecycleReadyEvent>(_ => readyReceived = true);
|
||||
_eventBus!.Register<ArchitectureEvents.ArchitectureDestroyingEvent>(_ => destroyingReceived = true);
|
||||
|
||||
|
||||
_eventBus.Send<ArchitectureEvents.ArchitectureLifecycleReadyEvent>();
|
||||
|
||||
|
||||
Assert.That(readyReceived, Is.True);
|
||||
Assert.That(destroyingReceived, Is.False);
|
||||
|
||||
|
||||
_eventBus.Send<ArchitectureEvents.ArchitectureDestroyingEvent>();
|
||||
|
||||
|
||||
Assert.That(destroyingReceived, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试事件可以在没有订阅者时发送
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Event_Can_Be_Sent_Without_Subscribers()
|
||||
{
|
||||
Assert.That(() => _eventBus!.Send<ArchitectureEvents.ArchitectureLifecycleReadyEvent>(),
|
||||
Assert.That(() => _eventBus!.Send<ArchitectureEvents.ArchitectureLifecycleReadyEvent>(),
|
||||
Throws.Nothing);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,9 +3,15 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.events;
|
||||
|
||||
/// <summary>
|
||||
/// EasyEvents功能测试类,用于验证事件系统的注册、触发和参数传递功能
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class EasyEventsTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试用例初始化方法,在每个测试方法执行前设置EasyEvents实例
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@ -14,6 +20,9 @@ public class EasyEventsTests
|
||||
|
||||
private EasyEvents _easyEvents = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 测试单参数事件的功能,验证事件能够正确接收并传递int类型参数
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Get_EventT_Should_Trigger_With_Parameter()
|
||||
{
|
||||
@ -21,11 +30,16 @@ public class EasyEventsTests
|
||||
var @event = EasyEvents.GetOrAdd<Event<int>>();
|
||||
|
||||
@event.Register(value => { receivedValue = value; });
|
||||
|
||||
// 触发事件并传递参数42
|
||||
@event.Trigger(42);
|
||||
|
||||
Assert.That(receivedValue, Is.EqualTo(42));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试双参数事件的功能,验证事件能够正确接收并传递int和string类型的参数
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Get_EventTTK_Should_Trigger_With_Two_Parameters()
|
||||
{
|
||||
@ -38,6 +52,8 @@ public class EasyEventsTests
|
||||
receivedInt = i;
|
||||
receivedString = s;
|
||||
});
|
||||
|
||||
// 触发事件并传递两个参数:整数100和字符串"hello"
|
||||
@event.Trigger(100, "hello");
|
||||
|
||||
Assert.That(receivedInt, Is.EqualTo(100));
|
||||
|
||||
@ -3,9 +3,15 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.events;
|
||||
|
||||
/// <summary>
|
||||
/// EventBus测试类,用于验证事件总线的各种功能
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class EventBusTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试设置方法,在每个测试方法执行前初始化EventBus实例
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@ -14,6 +20,10 @@ public class EventBusTests
|
||||
|
||||
private EventBus _eventBus = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 测试注册事件处理器的功能
|
||||
/// 验证注册的处理器能够在发送对应事件时被正确调用
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Register_Should_Add_Handler()
|
||||
{
|
||||
@ -25,6 +35,10 @@ public class EventBusTests
|
||||
Assert.That(called, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试注销事件处理器的功能
|
||||
/// 验证已注册的处理器在注销后不会再被调用
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void UnRegister_Should_Remove_Handler()
|
||||
{
|
||||
@ -33,13 +47,19 @@ public class EventBusTests
|
||||
Action<EventBusTestsEvent> handler = @event => { count++; };
|
||||
_eventBus.Register(handler);
|
||||
_eventBus.Send<EventBusTestsEvent>();
|
||||
// 验证处理器被调用一次
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
|
||||
_eventBus.UnRegister(handler);
|
||||
_eventBus.Send<EventBusTestsEvent>();
|
||||
// 验证处理器在注销后不再被调用
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试发送事件时调用所有处理器的功能
|
||||
/// 验证同一事件类型的多个处理器都能被正确调用
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SendEvent_Should_Invoke_All_Handlers()
|
||||
{
|
||||
@ -51,11 +71,15 @@ public class EventBusTests
|
||||
|
||||
_eventBus.Send<EventBusTestsEvent>();
|
||||
|
||||
// 验证所有处理器都被调用一次
|
||||
Assert.That(count1, Is.EqualTo(1));
|
||||
Assert.That(count2, Is.EqualTo(1));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EventBus测试专用事件类
|
||||
/// </summary>
|
||||
public class EventBusTestsEvent
|
||||
{
|
||||
}
|
||||
@ -3,9 +3,15 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.events;
|
||||
|
||||
/// <summary>
|
||||
/// 测试事件系统功能的测试类
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class EventTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 在每个测试方法执行前进行初始化设置
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@ -18,6 +24,9 @@ public class EventTests
|
||||
private Event<int> _eventInt = null!;
|
||||
private Event<int, string> _eventIntString = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 测试EasyEvent注册功能是否正确添加处理器
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void EasyEvent_Register_Should_Add_Handler()
|
||||
{
|
||||
@ -29,6 +38,9 @@ public class EventTests
|
||||
Assert.That(called, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试EasyEvent取消注册功能是否正确移除处理器
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void EasyEvent_UnRegister_Should_Remove_Handler()
|
||||
{
|
||||
@ -44,6 +56,9 @@ public class EventTests
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试EasyEvent多个处理器是否都能被调用
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void EasyEvent_Multiple_Handlers_Should_All_Be_Called()
|
||||
{
|
||||
@ -59,6 +74,9 @@ public class EventTests
|
||||
Assert.That(count2, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试带泛型参数的事件注册功能是否正确添加处理器
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void EventT_Register_Should_Add_Handler()
|
||||
{
|
||||
@ -70,6 +88,9 @@ public class EventTests
|
||||
Assert.That(receivedValue, Is.EqualTo(42));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试带泛型参数的事件取消注册功能是否正确移除处理器
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void EventT_UnRegister_Should_Remove_Handler()
|
||||
{
|
||||
@ -85,6 +106,9 @@ public class EventTests
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试带泛型参数的事件多个处理器是否都能被调用
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void EventT_Multiple_Handlers_Should_All_Be_Called()
|
||||
{
|
||||
@ -100,6 +124,9 @@ public class EventTests
|
||||
Assert.That(values, Does.Contain(10));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试带两个泛型参数的事件注册功能是否正确添加处理器
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void EventTTK_Register_Should_Add_Handler()
|
||||
{
|
||||
@ -117,6 +144,9 @@ public class EventTests
|
||||
Assert.That(receivedString, Is.EqualTo("test"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试带两个泛型参数的事件取消注册功能是否正确移除处理器
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void EventTTK_UnRegister_Should_Remove_Handler()
|
||||
{
|
||||
|
||||
@ -3,9 +3,16 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.events;
|
||||
|
||||
/// <summary>
|
||||
/// 测试OrEvent类的功能,验证其在多个事件中的逻辑或操作行为
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class OrEventTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试当任意一个事件触发时,OrEvent应该被触发
|
||||
/// 验证基本的OR逻辑功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void OrEvent_Should_Trigger_When_Any_Event_Fires()
|
||||
{
|
||||
@ -16,6 +23,7 @@ public class OrEventTests
|
||||
var triggered = false;
|
||||
orEvent.Register(() => { triggered = true; });
|
||||
|
||||
// 将两个事件添加到OrEvent中
|
||||
orEvent.Or(event1).Or(event2);
|
||||
|
||||
event1.Trigger(0);
|
||||
@ -23,6 +31,10 @@ public class OrEventTests
|
||||
Assert.That(triggered, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试当第二个事件触发时,OrEvent应该被触发
|
||||
/// 验证OR逻辑对所有注册事件都有效
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void OrEvent_Should_Trigger_When_Second_Event_Fires()
|
||||
{
|
||||
@ -33,6 +45,7 @@ public class OrEventTests
|
||||
var triggered = false;
|
||||
orEvent.Register(() => { triggered = true; });
|
||||
|
||||
// 将两个事件添加到OrEvent中
|
||||
orEvent.Or(event1).Or(event2);
|
||||
|
||||
event2.Trigger(0);
|
||||
@ -40,6 +53,10 @@ public class OrEventTests
|
||||
Assert.That(triggered, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试OrEvent支持多个处理程序
|
||||
/// 验证单个OrEvent可以注册多个回调函数
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void OrEvent_Should_Support_Multiple_Handlers()
|
||||
{
|
||||
@ -52,6 +69,7 @@ public class OrEventTests
|
||||
orEvent.Register(() => { count1++; });
|
||||
orEvent.Register(() => { count2++; });
|
||||
|
||||
// 将事件添加到OrEvent中
|
||||
orEvent.Or(@event);
|
||||
@event.Trigger(0);
|
||||
|
||||
@ -59,6 +77,10 @@ public class OrEventTests
|
||||
Assert.That(count2, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试UnRegister方法应该移除处理程序
|
||||
/// 验证注销功能能够正确移除已注册的回调函数
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void OrEvent_UnRegister_Should_Remove_Handler()
|
||||
{
|
||||
@ -74,6 +96,7 @@ public class OrEventTests
|
||||
@event.Trigger(0);
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
|
||||
// 注销处理程序
|
||||
orEvent.UnRegister(handler);
|
||||
@event.Trigger(0);
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
|
||||
@ -4,9 +4,15 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.events;
|
||||
|
||||
/// <summary>
|
||||
/// 注销功能测试类,用于测试不同类型的注销行为
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class UnRegisterTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试DefaultUnRegister在调用注销时是否正确触发回调函数
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void DefaultUnRegister_Should_InvokeCallback_When_UnRegisterCalled()
|
||||
{
|
||||
@ -18,6 +24,9 @@ public class UnRegisterTests
|
||||
Assert.That(invoked, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试DefaultUnRegister在注销后是否清除回调函数,防止重复执行
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void DefaultUnRegister_Should_ClearCallback_After_UnRegister()
|
||||
{
|
||||
@ -30,6 +39,9 @@ public class UnRegisterTests
|
||||
Assert.That(callCount, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试DefaultUnRegister在传入空回调函数时不会抛出异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void DefaultUnRegister_WithNullCallback_Should_NotThrow()
|
||||
{
|
||||
@ -38,6 +50,9 @@ public class UnRegisterTests
|
||||
Assert.DoesNotThrow(() => unRegister.UnRegister());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试BindablePropertyUnRegister是否能正确从属性中注销事件处理器
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void BindablePropertyUnRegister_Should_UnRegister_From_Property()
|
||||
{
|
||||
@ -55,6 +70,9 @@ public class UnRegisterTests
|
||||
Assert.That(callCount, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试BindablePropertyUnRegister在注销后是否清除内部引用
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void BindablePropertyUnRegister_Should_Clear_References()
|
||||
{
|
||||
@ -65,10 +83,14 @@ public class UnRegisterTests
|
||||
|
||||
unRegister.UnRegister();
|
||||
|
||||
// 验证注销后引用被清除
|
||||
Assert.That(unRegister.BindableProperty, Is.Null);
|
||||
Assert.That(unRegister.OnValueChanged, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试BindablePropertyUnRegister在传入空属性时不会抛出异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void BindablePropertyUnRegister_WithNull_Property_Should_NotThrow()
|
||||
{
|
||||
@ -78,6 +100,9 @@ public class UnRegisterTests
|
||||
Assert.DoesNotThrow(() => unRegister.UnRegister());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试BindablePropertyUnRegister在传入空处理器时不会抛出异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void BindablePropertyUnRegister_WithNull_Handler_Should_NotThrow()
|
||||
{
|
||||
|
||||
@ -3,9 +3,15 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.extensions;
|
||||
|
||||
/// <summary>
|
||||
/// 测试ObjectExtensions扩展方法的功能
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class ObjectExtensionsTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证IfType方法在类型匹配时执行指定操作
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IfType_Should_Execute_Action_When_Type_Matches()
|
||||
{
|
||||
@ -17,6 +23,9 @@ public class ObjectExtensionsTests
|
||||
Assert.That(executed, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证IfType方法在类型不匹配时不执行指定操作
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IfType_Should_Not_Execute_Action_When_Type_Does_Not_Match()
|
||||
{
|
||||
@ -28,6 +37,9 @@ public class ObjectExtensionsTests
|
||||
Assert.That(executed, Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证IfType方法在类型匹配且谓词条件为真时执行指定操作
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IfType_WithPredicate_Should_Execute_When_Type_Matches_And_Predicate_True()
|
||||
{
|
||||
@ -39,6 +51,9 @@ public class ObjectExtensionsTests
|
||||
Assert.That(executed, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证IfType方法在谓词条件为假时不执行指定操作
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IfType_WithPredicate_Should_Not_Execute_When_Predicate_False()
|
||||
{
|
||||
@ -50,6 +65,9 @@ public class ObjectExtensionsTests
|
||||
Assert.That(executed, Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证IfType方法在类型匹配时执行匹配操作,在类型不匹配时执行不匹配操作
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IfType_WithBoth_Actions_Should_Execute_Correct_Action()
|
||||
{
|
||||
@ -66,6 +84,9 @@ public class ObjectExtensionsTests
|
||||
Assert.That(noMatchCount, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证IfType方法在类型匹配时返回转换结果
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IfType_WithResult_Should_Return_Value_When_Type_Matches()
|
||||
{
|
||||
@ -76,6 +97,9 @@ public class ObjectExtensionsTests
|
||||
Assert.That(result, Is.EqualTo("Test"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证IfType方法在类型不匹配时返回默认值
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IfType_WithResult_Should_Return_Default_When_Type_Does_Not_Match()
|
||||
{
|
||||
@ -86,6 +110,9 @@ public class ObjectExtensionsTests
|
||||
Assert.That(result, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证As方法在类型匹配时返回实例
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void As_Should_Return_Instance_When_Type_Matches()
|
||||
{
|
||||
@ -97,6 +124,9 @@ public class ObjectExtensionsTests
|
||||
Assert.That(result, Is.SameAs(obj));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证As方法在类型不匹配时返回null
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void As_Should_Return_Null_When_Type_Does_Not_Match()
|
||||
{
|
||||
@ -107,6 +137,9 @@ public class ObjectExtensionsTests
|
||||
Assert.That(result, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Do方法执行操作并返回对象本身
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Do_Should_Execute_Action_And_Return_Object()
|
||||
{
|
||||
@ -118,6 +151,9 @@ public class ObjectExtensionsTests
|
||||
Assert.That(obj.Value, Is.EqualTo(10));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Do方法支持链式调用
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Do_Should_Support_Chaining()
|
||||
{
|
||||
@ -130,6 +166,9 @@ public class ObjectExtensionsTests
|
||||
Assert.That(obj.Name, Is.EqualTo("B"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证SwitchType方法执行匹配的处理器
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SwitchType_Should_Execute_Matching_Handler()
|
||||
{
|
||||
@ -144,6 +183,9 @@ public class ObjectExtensionsTests
|
||||
Assert.That(executed, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证SwitchType方法只执行第一个匹配的处理器
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SwitchType_Should_Execute_First_Matching_Handler()
|
||||
{
|
||||
@ -158,6 +200,9 @@ public class ObjectExtensionsTests
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证SwitchType方法在没有匹配项时不执行任何处理器
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SwitchType_Should_Not_Execute_When_No_Match()
|
||||
{
|
||||
@ -173,8 +218,18 @@ public class ObjectExtensionsTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用的简单类
|
||||
/// </summary>
|
||||
public class TestClass
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置整数值
|
||||
/// </summary>
|
||||
public int Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置名称字符串
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
}
|
||||
@ -5,9 +5,15 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.extensions;
|
||||
|
||||
/// <summary>
|
||||
/// 测试UnRegisterList扩展方法的功能
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class UnRegisterListExtensionTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 在每个测试方法执行前初始化测试环境
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@ -16,6 +22,9 @@ public class UnRegisterListExtensionTests
|
||||
|
||||
private TestUnRegisterList _unRegisterList = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 验证AddToUnregisterList方法能够正确将元素添加到列表中
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void AddToUnregisterList_Should_Add_To_List()
|
||||
{
|
||||
@ -26,6 +35,9 @@ public class UnRegisterListExtensionTests
|
||||
Assert.That(_unRegisterList.UnregisterList.Count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证AddToUnregisterList方法能够正确添加多个元素到列表中
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void AddToUnregisterList_Should_Add_Multiple_Elements()
|
||||
{
|
||||
@ -40,6 +52,9 @@ public class UnRegisterListExtensionTests
|
||||
Assert.That(_unRegisterList.UnregisterList.Count, Is.EqualTo(3));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证UnRegisterAll方法能够正确注销所有元素
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void UnRegisterAll_Should_UnRegister_All_Elements()
|
||||
{
|
||||
@ -55,6 +70,7 @@ public class UnRegisterListExtensionTests
|
||||
unRegister2.AddToUnregisterList(_unRegisterList);
|
||||
unRegister3.AddToUnregisterList(_unRegisterList);
|
||||
|
||||
// 执行注销操作
|
||||
_unRegisterList.UnRegisterAll();
|
||||
|
||||
Assert.That(invoked1, Is.True);
|
||||
@ -62,23 +78,33 @@ public class UnRegisterListExtensionTests
|
||||
Assert.That(invoked3, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证UnRegisterAll方法在执行后会清空列表
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void UnRegisterAll_Should_Clear_List()
|
||||
{
|
||||
var unRegister = new DefaultUnRegister(() => { });
|
||||
unRegister.AddToUnregisterList(_unRegisterList);
|
||||
|
||||
// 执行注销操作
|
||||
_unRegisterList.UnRegisterAll();
|
||||
|
||||
Assert.That(_unRegisterList.UnregisterList.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证UnRegisterAll方法在空列表情况下不会抛出异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void UnRegisterAll_Should_Not_Throw_When_Empty()
|
||||
{
|
||||
Assert.DoesNotThrow(() => _unRegisterList.UnRegisterAll());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证UnRegisterAll方法对每个元素只调用一次注销操作
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void UnRegisterAll_Should_Invoke_Once_Per_Element()
|
||||
{
|
||||
@ -87,13 +113,20 @@ public class UnRegisterListExtensionTests
|
||||
|
||||
unRegister.AddToUnregisterList(_unRegisterList);
|
||||
|
||||
// 执行注销操作
|
||||
_unRegisterList.UnRegisterAll();
|
||||
|
||||
Assert.That(callCount, Is.EqualTo(1));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用的UnRegisterList实现类,用于验证扩展方法功能
|
||||
/// </summary>
|
||||
public class TestUnRegisterList : IUnRegisterList
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置注销列表
|
||||
/// </summary>
|
||||
public IList<IUnRegister> UnregisterList { get; } = new List<IUnRegister>();
|
||||
}
|
||||
@ -6,9 +6,15 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.ioc;
|
||||
|
||||
/// <summary>
|
||||
/// 测试 IoC 容器功能的单元测试类
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class IocContainerTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 在每个测试方法执行前进行设置
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@ -26,6 +32,9 @@ public class IocContainerTests
|
||||
private IocContainer _container = null!;
|
||||
private readonly Dictionary<Type, object> _mockContextServices = new();
|
||||
|
||||
/// <summary>
|
||||
/// 测试注册单例实例的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void RegisterSingleton_Should_Register_Instance()
|
||||
{
|
||||
@ -34,6 +43,9 @@ public class IocContainerTests
|
||||
Assert.DoesNotThrow(() => _container.RegisterSingleton(instance));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试重复注册单例时应抛出 InvalidOperationException 异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void RegisterSingleton_WithDuplicate_Should_ThrowInvalidOperationException()
|
||||
{
|
||||
@ -45,6 +57,9 @@ public class IocContainerTests
|
||||
Assert.Throws<InvalidOperationException>(() => _container.RegisterSingleton(instance2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试在容器冻结后注册单例时应抛出 InvalidOperationException 异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void RegisterSingleton_AfterFreeze_Should_ThrowInvalidOperationException()
|
||||
{
|
||||
@ -54,6 +69,9 @@ public class IocContainerTests
|
||||
Assert.Throws<InvalidOperationException>(() => _container.RegisterSingleton(instance));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试注册多样性实例到所有类型的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void RegisterPlurality_Should_Register_Instance_To_All_Types()
|
||||
{
|
||||
@ -65,6 +83,9 @@ public class IocContainerTests
|
||||
Assert.That(_container.Contains<IService>(), Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试在容器冻结后注册多样性实例时应抛出 InvalidOperationException 异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void RegisterPlurality_AfterFreeze_Should_ThrowInvalidOperationException()
|
||||
{
|
||||
@ -74,6 +95,9 @@ public class IocContainerTests
|
||||
Assert.Throws<InvalidOperationException>(() => _container.RegisterPlurality(instance));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试泛型注册实例的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Register_Generic_Should_Register_Instance()
|
||||
{
|
||||
@ -84,6 +108,9 @@ public class IocContainerTests
|
||||
Assert.That(_container.Contains<TestService>(), Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试在容器冻结后使用泛型注册时应抛出 InvalidOperationException 异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Register_Generic_AfterFreeze_Should_ThrowInvalidOperationException()
|
||||
{
|
||||
@ -93,6 +120,9 @@ public class IocContainerTests
|
||||
Assert.Throws<InvalidOperationException>(() => _container.Register(instance));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试按类型注册实例的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Register_Type_Should_Register_Instance()
|
||||
{
|
||||
@ -103,6 +133,9 @@ public class IocContainerTests
|
||||
Assert.That(_container.Contains<TestService>(), Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试获取第一个实例的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Get_Should_Return_First_Instance()
|
||||
{
|
||||
@ -115,6 +148,9 @@ public class IocContainerTests
|
||||
Assert.That(result, Is.SameAs(instance));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试当没有实例时获取应返回 null 的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Get_WithNoInstances_Should_ReturnNull()
|
||||
{
|
||||
@ -123,6 +159,9 @@ public class IocContainerTests
|
||||
Assert.That(result, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试获取必需的单个实例的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetRequired_Should_Return_Single_Instance()
|
||||
{
|
||||
@ -135,12 +174,18 @@ public class IocContainerTests
|
||||
Assert.That(result, Is.SameAs(instance));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试当没有实例时获取必需实例应抛出 InvalidOperationException 异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetRequired_WithNoInstances_Should_ThrowInvalidOperationException()
|
||||
{
|
||||
Assert.Throws<InvalidOperationException>(() => _container.GetRequired<TestService>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试当有多个实例时获取必需实例应抛出 InvalidOperationException 异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetRequired_WithMultipleInstances_Should_ThrowInvalidOperationException()
|
||||
{
|
||||
@ -150,6 +195,9 @@ public class IocContainerTests
|
||||
Assert.Throws<InvalidOperationException>(() => _container.GetRequired<TestService>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试获取所有实例的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetAll_Should_Return_All_Instances()
|
||||
{
|
||||
@ -166,6 +214,9 @@ public class IocContainerTests
|
||||
Assert.That(results, Does.Contain(instance2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试当没有实例时获取所有实例应返回空数组的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetAll_WithNoInstances_Should_Return_Empty_Array()
|
||||
{
|
||||
@ -174,6 +225,9 @@ public class IocContainerTests
|
||||
Assert.That(results.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试获取排序后的所有实例的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetAllSorted_Should_Return_Sorted_Instances()
|
||||
{
|
||||
@ -189,6 +243,9 @@ public class IocContainerTests
|
||||
Assert.That(results[2].Priority, Is.EqualTo(3));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试当存在实例时检查包含关系应返回 true 的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Contains_WithExistingInstance_Should_ReturnTrue()
|
||||
{
|
||||
@ -198,12 +255,18 @@ public class IocContainerTests
|
||||
Assert.That(_container.Contains<TestService>(), Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试当不存在实例时检查包含关系应返回 false 的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Contains_WithNoInstances_Should_ReturnFalse()
|
||||
{
|
||||
Assert.That(_container.Contains<TestService>(), Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试当实例存在时检查实例包含关系应返回 true 的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ContainsInstance_WithExistingInstance_Should_ReturnTrue()
|
||||
{
|
||||
@ -213,6 +276,9 @@ public class IocContainerTests
|
||||
Assert.That(_container.ContainsInstance(instance), Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试当实例不存在时检查实例包含关系应返回 false 的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ContainsInstance_WithNonExistingInstance_Should_ReturnFalse()
|
||||
{
|
||||
@ -221,6 +287,9 @@ public class IocContainerTests
|
||||
Assert.That(_container.ContainsInstance(instance), Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试清除所有实例的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Clear_Should_Remove_All_Instances()
|
||||
{
|
||||
@ -232,6 +301,9 @@ public class IocContainerTests
|
||||
Assert.That(_container.Contains<TestService>(), Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试冻结容器以防止进一步注册的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Freeze_Should_Prevent_Further_Registrations()
|
||||
{
|
||||
@ -243,6 +315,9 @@ public class IocContainerTests
|
||||
Assert.Throws<InvalidOperationException>(() => _container.Register(instance2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试注册系统实例的功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void RegisterSystem_Should_Register_Instance()
|
||||
{
|
||||
@ -254,9 +329,18 @@ public class IocContainerTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 服务接口定义
|
||||
/// </summary>
|
||||
public interface IService;
|
||||
|
||||
/// <summary>
|
||||
/// 测试服务类,实现 IService 接口
|
||||
/// </summary>
|
||||
public sealed class TestService : IService
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置优先级
|
||||
/// </summary>
|
||||
public int Priority { get; set; }
|
||||
}
|
||||
@ -4,9 +4,16 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.logging;
|
||||
|
||||
/// <summary>
|
||||
/// 测试ConsoleLogger类的功能和行为的单元测试类
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class ConsoleLoggerTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 在每个测试方法执行前设置测试环境
|
||||
/// 创建StringWriter和ConsoleLogger实例用于测试
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@ -14,6 +21,10 @@ public class ConsoleLoggerTests
|
||||
_logger = new ConsoleLogger("TestLogger", LogLevel.Info, _stringWriter, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在每个测试方法执行后清理测试资源
|
||||
/// 释放StringWriter资源
|
||||
/// </summary>
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
@ -23,6 +34,10 @@ public class ConsoleLoggerTests
|
||||
private StringWriter _stringWriter = null!;
|
||||
private ConsoleLogger _logger = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 测试使用默认名称构造函数时是否正确使用根日志器名称
|
||||
/// 验证当未指定名称时,日志器使用"ROOT"作为默认名称
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Constructor_WithDefaultName_ShouldUseRootLoggerName()
|
||||
{
|
||||
@ -31,6 +46,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(defaultLogger.Name(), Is.EqualTo("ROOT"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试使用自定义名称构造函数时是否正确使用自定义名称
|
||||
/// 验证构造函数能够正确设置并返回指定的日志器名称
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Constructor_WithCustomName_ShouldUseCustomName()
|
||||
{
|
||||
@ -39,6 +58,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(customLogger.Name(), Is.EqualTo("CustomLogger"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试使用自定义最小级别构造函数时是否正确遵循最小日志级别
|
||||
/// 验证只有达到或超过最小级别的日志消息才会被记录
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Constructor_WithCustomMinLevel_ShouldRespectMinLevel()
|
||||
{
|
||||
@ -52,6 +75,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(output, Does.Not.Contain("TRACE"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试使用自定义写入器构造函数时是否将日志写入到自定义写入器
|
||||
/// 验证日志消息能够正确写入到指定的StringWriter中
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Constructor_WithCustomWriter_ShouldWriteToCustomWriter()
|
||||
{
|
||||
@ -61,6 +88,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(output, Does.Contain("Test message"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试写入操作是否包含时间戳信息
|
||||
/// 验证每条日志消息都包含格式化的日期时间信息
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Write_ShouldIncludeTimestamp()
|
||||
{
|
||||
@ -70,6 +101,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(output, Does.Match(@"\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}\]"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试写入操作是否包含日志级别信息
|
||||
/// 验证不同级别的日志消息都能正确显示对应的级别标识
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Write_ShouldIncludeLevel()
|
||||
{
|
||||
@ -84,6 +119,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(output, Does.Contain("ERROR"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试写入操作是否包含日志器名称
|
||||
/// 验证日志输出中包含创建时指定的日志器名称
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Write_ShouldIncludeLoggerName()
|
||||
{
|
||||
@ -93,6 +132,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(output, Does.Contain("[TestLogger]"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试写入操作在包含异常时是否正确包含异常信息
|
||||
/// 验证异常的详细信息能够正确记录在日志中
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Write_WithException_ShouldIncludeException()
|
||||
{
|
||||
@ -104,6 +147,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(output, Does.Contain("Test exception"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试写入多行日志时是否正确格式化
|
||||
/// 验证多条日志消息能够正确分行显示且包含正确的级别信息
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Write_WithMultipleLines_ShouldFormatCorrectly()
|
||||
{
|
||||
@ -120,6 +167,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(lines[2], Does.Contain("ERROR"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试写入格式化消息时是否正确格式化
|
||||
/// 验证带参数的消息格式化功能正常工作
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Write_WithFormattedMessage_ShouldFormatCorrectly()
|
||||
{
|
||||
@ -129,6 +180,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(output, Does.Contain("Value: 42"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试写入操作是否遵循最小日志级别限制
|
||||
/// 验证低于最小级别的日志消息不会被记录
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Write_ShouldRespectMinLevel()
|
||||
{
|
||||
@ -142,6 +197,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(output, Does.Not.Contain("Trace message"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试启用颜色功能时是否不影响输出内容
|
||||
/// 验证即使颜色功能被禁用,日志内容仍然正确记录
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Write_WithColorsEnabled_ShouldNotAffectOutputContent()
|
||||
{
|
||||
@ -153,6 +212,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(output, Does.Contain("Colored message"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试所有日志级别是否都能正确格式化
|
||||
/// 验证从Trace到Fatal的所有日志级别都能正确显示
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Write_AllLogLevels_ShouldFormatCorrectly()
|
||||
{
|
||||
@ -170,6 +233,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(output, Does.Contain("FATAL"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试写入嵌套异常时是否包含完整的异常信息
|
||||
/// 验证嵌套异常的所有层级信息都能被正确记录
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Write_WithNestedException_ShouldIncludeFullException()
|
||||
{
|
||||
@ -184,6 +251,10 @@ public class ConsoleLoggerTests
|
||||
Assert.That(output, Does.Contain("Inner exception"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试使用空写入器时是否不会抛出异常
|
||||
/// 验证当传入null写入器时,日志器能够安全处理而不崩溃
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Write_WithNullWriter_ShouldNotThrow()
|
||||
{
|
||||
@ -192,6 +263,10 @@ public class ConsoleLoggerTests
|
||||
Assert.DoesNotThrow(() => logger.Info("Test message"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试写入空消息时是否仍能正常写入
|
||||
/// 验证即使消息为空字符串,日志框架仍能生成包含其他信息的完整日志条目
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Write_WithEmptyMessage_ShouldStillWrite()
|
||||
{
|
||||
|
||||
@ -4,9 +4,15 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.logging;
|
||||
|
||||
/// <summary>
|
||||
/// 测试LoggerFactory相关功能的测试类
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class LoggerFactoryTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试ConsoleLoggerFactory的GetLogger方法是否返回ConsoleLogger实例
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ConsoleLoggerFactory_GetLogger_ShouldReturnConsoleLogger()
|
||||
{
|
||||
@ -18,6 +24,9 @@ public class LoggerFactoryTests
|
||||
Assert.That(logger.Name(), Is.EqualTo("TestLogger"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ConsoleLoggerFactory使用不同名称获取不同的logger实例
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ConsoleLoggerFactory_GetLogger_WithDifferentNames_ShouldReturnDifferentLoggers()
|
||||
{
|
||||
@ -29,6 +38,9 @@ public class LoggerFactoryTests
|
||||
Assert.That(logger2.Name(), Is.EqualTo("Logger2"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ConsoleLoggerFactory使用默认最小级别时的行为(默认为Info级别)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ConsoleLoggerFactory_GetLogger_WithDefaultMinLevel_ShouldUseInfo()
|
||||
{
|
||||
@ -38,6 +50,7 @@ public class LoggerFactoryTests
|
||||
var stringWriter = new StringWriter();
|
||||
var testLogger = new ConsoleLogger("TestLogger", LogLevel.Info, stringWriter, false);
|
||||
|
||||
// 验证Debug消息不会被记录,但Info消息会被记录
|
||||
testLogger.Debug("Debug message");
|
||||
testLogger.Info("Info message");
|
||||
|
||||
@ -46,6 +59,9 @@ public class LoggerFactoryTests
|
||||
Assert.That(output, Does.Contain("Info message"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ConsoleLoggerFactoryProvider创建logger时使用提供者的最小级别设置
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ConsoleLoggerFactoryProvider_CreateLogger_ShouldReturnLoggerWithProviderMinLevel()
|
||||
{
|
||||
@ -55,6 +71,7 @@ public class LoggerFactoryTests
|
||||
var stringWriter = new StringWriter();
|
||||
var testLogger = new ConsoleLogger("TestLogger", LogLevel.Debug, stringWriter, false);
|
||||
|
||||
// 验证Debug消息会被记录,但Trace消息不会被记录
|
||||
testLogger.Debug("Debug message");
|
||||
testLogger.Trace("Trace message");
|
||||
|
||||
@ -63,6 +80,9 @@ public class LoggerFactoryTests
|
||||
Assert.That(output, Does.Not.Contain("Trace message"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ConsoleLoggerFactoryProvider创建logger时使用提供的名称
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ConsoleLoggerFactoryProvider_CreateLogger_ShouldUseProvidedName()
|
||||
{
|
||||
@ -72,6 +92,9 @@ public class LoggerFactoryTests
|
||||
Assert.That(logger.Name(), Is.EqualTo("MyLogger"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试LoggerFactoryResolver的Provider属性是否有默认值
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void LoggerFactoryResolver_Provider_ShouldHaveDefaultValue()
|
||||
{
|
||||
@ -79,6 +102,9 @@ public class LoggerFactoryTests
|
||||
Assert.That(LoggerFactoryResolver.Provider, Is.InstanceOf<ConsoleLoggerFactoryProvider>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试LoggerFactoryResolver的Provider属性可以被更改
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void LoggerFactoryResolver_Provider_CanBeChanged()
|
||||
{
|
||||
@ -92,12 +118,18 @@ public class LoggerFactoryTests
|
||||
LoggerFactoryResolver.Provider = originalProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试LoggerFactoryResolver的MinLevel属性是否有默认值
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void LoggerFactoryResolver_MinLevel_ShouldHaveDefaultValue()
|
||||
{
|
||||
Assert.That(LoggerFactoryResolver.MinLevel, Is.EqualTo(LogLevel.Info));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试LoggerFactoryResolver的MinLevel属性可以被更改
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void LoggerFactoryResolver_MinLevel_CanBeChanged()
|
||||
{
|
||||
@ -110,6 +142,9 @@ public class LoggerFactoryTests
|
||||
LoggerFactoryResolver.MinLevel = originalLevel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ConsoleLoggerFactoryProvider的MinLevel属性是否有默认值
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ConsoleLoggerFactoryProvider_MinLevel_ShouldHaveDefaultValue()
|
||||
{
|
||||
@ -118,6 +153,9 @@ public class LoggerFactoryTests
|
||||
Assert.That(provider.MinLevel, Is.EqualTo(LogLevel.Info));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ConsoleLoggerFactoryProvider的MinLevel属性可以被更改
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ConsoleLoggerFactoryProvider_MinLevel_CanBeChanged()
|
||||
{
|
||||
@ -128,6 +166,9 @@ public class LoggerFactoryTests
|
||||
Assert.That(provider.MinLevel, Is.EqualTo(LogLevel.Debug));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试LoggerFactoryResolver的Provider创建logger时使用提供者设置
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void LoggerFactoryResolver_Provider_CreateLogger_ShouldUseProviderSettings()
|
||||
{
|
||||
@ -141,6 +182,7 @@ public class LoggerFactoryTests
|
||||
var stringWriter = new StringWriter();
|
||||
var testLogger = new ConsoleLogger("TestLogger", LogLevel.Warning, stringWriter, false);
|
||||
|
||||
// 验证Warn消息会被记录,但Info消息不会被记录
|
||||
testLogger.Warn("Warn message");
|
||||
testLogger.Info("Info message");
|
||||
|
||||
@ -151,6 +193,9 @@ public class LoggerFactoryTests
|
||||
LoggerFactoryResolver.Provider = originalProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试LoggerFactoryResolver的MinLevel属性影响新创建的logger
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void LoggerFactoryResolver_MinLevel_AffectsNewLoggers()
|
||||
{
|
||||
@ -164,6 +209,7 @@ public class LoggerFactoryTests
|
||||
var stringWriter = new StringWriter();
|
||||
var testLogger = new ConsoleLogger("TestLogger", LogLevel.Error, stringWriter, false);
|
||||
|
||||
// 验证Error消息会被记录,但Warn消息不会被记录
|
||||
testLogger.Error("Error message");
|
||||
testLogger.Warn("Warn message");
|
||||
|
||||
@ -174,6 +220,9 @@ public class LoggerFactoryTests
|
||||
LoggerFactoryResolver.MinLevel = originalMinLevel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ConsoleLoggerFactory创建的多个logger实例是独立的
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ConsoleLoggerFactory_MultipleLoggers_ShouldBeIndependent()
|
||||
{
|
||||
@ -185,6 +234,9 @@ public class LoggerFactoryTests
|
||||
Assert.That(logger2.Name(), Is.EqualTo("Logger2"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ConsoleLoggerFactoryProvider的MinLevel不会影响已创建的logger
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ConsoleLoggerFactoryProvider_MinLevel_DoesNotAffectCreatedLogger()
|
||||
{
|
||||
@ -194,6 +246,7 @@ public class LoggerFactoryTests
|
||||
var stringWriter = new StringWriter();
|
||||
var testLogger = new ConsoleLogger("TestLogger", LogLevel.Error, stringWriter, false);
|
||||
|
||||
// 验证Error和Fatal消息都会被记录
|
||||
testLogger.Error("Error message");
|
||||
testLogger.Fatal("Fatal message");
|
||||
|
||||
|
||||
@ -4,9 +4,16 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.logging;
|
||||
|
||||
/// <summary>
|
||||
/// 测试Logger功能的单元测试类
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class LoggerTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 在每个测试方法执行前设置测试环境
|
||||
/// 创建一个新的TestLogger实例,名称为"TestLogger",最小日志级别为Info
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@ -15,6 +22,9 @@ public class LoggerTests
|
||||
|
||||
private TestLogger _logger = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 验证Name方法是否正确返回Logger的名称
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Name_Should_ReturnLoggerName()
|
||||
{
|
||||
@ -23,6 +33,9 @@ public class LoggerTests
|
||||
Assert.That(name, Is.EqualTo("TestLogger"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当使用默认名称时,Name方法是否返回根Logger名称"ROOT"
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Name_WithDefaultName_Should_ReturnRootLoggerName()
|
||||
{
|
||||
@ -31,42 +44,63 @@ public class LoggerTests
|
||||
Assert.That(defaultLogger.Name(), Is.EqualTo("ROOT"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当最小日志级别为Info时,IsTraceEnabled方法是否返回false
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IsTraceEnabled_WithInfoMinLevel_Should_ReturnFalse()
|
||||
{
|
||||
Assert.That(_logger.IsTraceEnabled(), Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当最小日志级别为Info时,IsDebugEnabled方法是否返回false
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IsDebugEnabled_WithInfoMinLevel_Should_ReturnFalse()
|
||||
{
|
||||
Assert.That(_logger.IsDebugEnabled(), Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当最小日志级别为Info时,IsInfoEnabled方法是否返回true
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IsInfoEnabled_WithInfoMinLevel_Should_ReturnTrue()
|
||||
{
|
||||
Assert.That(_logger.IsInfoEnabled(), Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当最小日志级别为Info时,IsWarnEnabled方法是否返回true
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IsWarnEnabled_WithInfoMinLevel_Should_ReturnTrue()
|
||||
{
|
||||
Assert.That(_logger.IsWarnEnabled(), Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当最小日志级别为Info时,IsErrorEnabled方法是否返回true
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IsErrorEnabled_WithInfoMinLevel_Should_ReturnTrue()
|
||||
{
|
||||
Assert.That(_logger.IsErrorEnabled(), Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当最小日志级别为Info时,IsFatalEnabled方法是否返回true
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IsFatalEnabled_WithInfoMinLevel_Should_ReturnTrue()
|
||||
{
|
||||
Assert.That(_logger.IsFatalEnabled(), Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证IsEnabledForLevel方法对于不同日志级别的返回值是否正确
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IsEnabledForLevel_WithValidLevel_Should_ReturnCorrectResult()
|
||||
{
|
||||
@ -78,12 +112,18 @@ public class LoggerTests
|
||||
Assert.That(_logger.IsEnabledForLevel(LogLevel.Fatal), Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当传入无效的日志级别时,IsEnabledForLevel方法是否会抛出ArgumentException异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void IsEnabledForLevel_WithInvalidLevel_Should_ThrowArgumentException()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => { _logger.IsEnabledForLevel((LogLevel)999); });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当Trace级别被禁用时,Trace方法不会写入日志
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Trace_ShouldNotWrite_WhenTraceDisabled()
|
||||
{
|
||||
@ -92,6 +132,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当Trace级别被禁用时,带格式化参数的Trace方法不会写入日志
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Trace_WithFormat_ShouldNotWrite_WhenTraceDisabled()
|
||||
{
|
||||
@ -100,6 +143,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当Trace级别被禁用时,带两个参数的Trace方法不会写入日志
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Trace_WithTwoArgs_ShouldNotWrite_WhenTraceDisabled()
|
||||
{
|
||||
@ -108,6 +154,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当Trace级别被禁用时,带异常参数的Trace方法不会写入日志
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Trace_WithException_ShouldNotWrite_WhenTraceDisabled()
|
||||
{
|
||||
@ -117,6 +166,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当Debug级别被禁用时,Debug方法不会写入日志
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Debug_ShouldNotWrite_WhenDebugDisabled()
|
||||
{
|
||||
@ -125,6 +177,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当Debug级别被禁用时,带格式化参数的Debug方法不会写入日志
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Debug_WithFormat_ShouldNotWrite_WhenDebugDisabled()
|
||||
{
|
||||
@ -133,6 +188,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当Info级别启用时,Info方法会正确写入日志
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Info_ShouldWrite_WhenInfoEnabled()
|
||||
{
|
||||
@ -144,6 +202,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Exception, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证带格式化参数的Info方法会正确写入格式化后的消息
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Info_WithFormat_ShouldWriteFormattedMessage()
|
||||
{
|
||||
@ -153,6 +214,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted message"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证带两个参数的Info方法会正确写入格式化后的消息
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Info_WithTwoArgs_ShouldWriteFormattedMessage()
|
||||
{
|
||||
@ -162,6 +226,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted arg1 and arg2"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证带多个参数的Info方法会正确写入格式化后的消息
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Info_WithMultipleArgs_ShouldWriteFormattedMessage()
|
||||
{
|
||||
@ -171,6 +238,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted arg1, arg2, arg3"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证带异常参数的Info方法会正确写入消息和异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Info_WithException_ShouldWriteMessageAndException()
|
||||
{
|
||||
@ -182,6 +252,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Exception, Is.SameAs(exception));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当Warn级别启用时,Warn方法会正确写入日志
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Warn_ShouldWrite_WhenWarnEnabled()
|
||||
{
|
||||
@ -192,6 +265,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Warn message"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证带格式化参数的Warn方法会正确写入格式化后的消息
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Warn_WithFormat_ShouldWriteFormattedMessage()
|
||||
{
|
||||
@ -201,6 +277,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted message"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证带异常参数的Warn方法会正确写入消息和异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Warn_WithException_ShouldWriteMessageAndException()
|
||||
{
|
||||
@ -211,6 +290,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Exception, Is.SameAs(exception));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当Error级别启用时,Error方法会正确写入日志
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Error_ShouldWrite_WhenErrorEnabled()
|
||||
{
|
||||
@ -221,6 +303,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Error message"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证带格式化参数的Error方法会正确写入格式化后的消息
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Error_WithFormat_ShouldWriteFormattedMessage()
|
||||
{
|
||||
@ -230,6 +315,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted message"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证带异常参数的Error方法会正确写入消息和异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Error_WithException_ShouldWriteMessageAndException()
|
||||
{
|
||||
@ -240,6 +328,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Exception, Is.SameAs(exception));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当Fatal级别启用时,Fatal方法会正确写入日志
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Fatal_ShouldWrite_WhenFatalEnabled()
|
||||
{
|
||||
@ -250,6 +341,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Fatal message"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证带格式化参数的Fatal方法会正确写入格式化后的消息
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Fatal_WithFormat_ShouldWriteFormattedMessage()
|
||||
{
|
||||
@ -259,6 +353,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted message"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证带异常参数的Fatal方法会正确写入消息和异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Fatal_WithException_ShouldWriteMessageAndException()
|
||||
{
|
||||
@ -269,6 +366,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[0].Exception, Is.SameAs(exception));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证多次调用日志方法会累积日志条目
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void MultipleLogCalls_ShouldAccumulateLogs()
|
||||
{
|
||||
@ -282,6 +382,9 @@ public class LoggerTests
|
||||
Assert.That(_logger.Logs[2].Message, Is.EqualTo("Message 3"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当最小日志级别设置为Trace时,所有级别的日志都会被启用
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Logger_WithTraceMinLevel_ShouldEnableAllLevels()
|
||||
{
|
||||
@ -297,6 +400,9 @@ public class LoggerTests
|
||||
Assert.That(traceLogger.Logs.Count, Is.EqualTo(6));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当最小日志级别设置为Fatal时,只有Fatal级别的日志会被启用
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Logger_WithFatalMinLevel_ShouldDisableAllButFatal()
|
||||
{
|
||||
@ -314,18 +420,41 @@ public class LoggerTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用的日志记录器实现类,继承自AbstractLogger
|
||||
/// </summary>
|
||||
public sealed class TestLogger : AbstractLogger
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化TestLogger的新实例
|
||||
/// </summary>
|
||||
/// <param name="name">日志记录器的名称,默认为null</param>
|
||||
/// <param name="minLevel">最小日志级别,默认为LogLevel.Info</param>
|
||||
public TestLogger(string? name = null, LogLevel minLevel = LogLevel.Info) : base(name, minLevel)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取记录的日志条目列表
|
||||
/// </summary>
|
||||
public List<LogEntry> Logs { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 将日志信息写入内部存储
|
||||
/// </summary>
|
||||
/// <param name="level">日志级别</param>
|
||||
/// <param name="message">日志消息</param>
|
||||
/// <param name="exception">相关异常(可选)</param>
|
||||
protected override void Write(LogLevel level, string message, Exception? exception)
|
||||
{
|
||||
Logs.Add(new LogEntry(level, message, exception));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表示单个日志条目的记录类型
|
||||
/// </summary>
|
||||
/// <param name="Level">日志级别</param>
|
||||
/// <param name="Message">日志消息</param>
|
||||
/// <param name="Exception">相关异常(可选)</param>
|
||||
public sealed record LogEntry(LogLevel Level, string Message, Exception? Exception);
|
||||
}
|
||||
@ -4,17 +4,29 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.pool;
|
||||
|
||||
/// <summary>
|
||||
/// 对象池功能测试类,用于验证对象池的基本操作和行为
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class ObjectPoolTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试初始化方法,在每个测试方法执行前设置测试环境
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_pool = new TestObjectPool();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用的对象池实例
|
||||
/// </summary>
|
||||
private TestObjectPool _pool = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 验证当对象池为空时,Acquire方法应该创建新对象
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Acquire_Should_Create_New_Object_When_Pool_Empty()
|
||||
{
|
||||
@ -25,6 +37,9 @@ public class ObjectPoolTests
|
||||
Assert.That(obj.OnAcquireCalled, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Acquire方法应该返回池中的可用对象
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Acquire_Should_Return_Pooled_Object()
|
||||
{
|
||||
@ -40,6 +55,9 @@ public class ObjectPoolTests
|
||||
Assert.That(obj2.OnAcquireCalled, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Release方法应该调用对象的OnRelease回调
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Release_Should_Call_OnRelease()
|
||||
{
|
||||
@ -50,6 +68,9 @@ public class ObjectPoolTests
|
||||
Assert.That(obj.OnReleaseCalled, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证Clear方法应该销毁所有对象
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Clear_Should_Destroy_All_Objects()
|
||||
{
|
||||
@ -65,6 +86,9 @@ public class ObjectPoolTests
|
||||
Assert.That(obj2.OnPoolDestroyCalled, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证多个池键应该相互独立
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Multiple_Pools_Should_Be_Independent()
|
||||
{
|
||||
@ -80,6 +104,9 @@ public class ObjectPoolTests
|
||||
Assert.That(obj4, Is.Not.SameAs(obj2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证OnAcquire回调应该在新对象和池中对象上都被调用
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void OnAcquire_Should_Be_Called_On_New_And_Pooled_Objects()
|
||||
{
|
||||
@ -94,36 +121,78 @@ public class ObjectPoolTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用对象池实现类,继承自AbstractObjectPoolSystem
|
||||
/// </summary>
|
||||
public class TestObjectPool : AbstractObjectPoolSystem<string, TestPoolableObject>
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建新的池化对象
|
||||
/// </summary>
|
||||
/// <param name="key">用于标识对象的键</param>
|
||||
/// <returns>新创建的TestPoolableObject实例</returns>
|
||||
protected override TestPoolableObject Create(string key)
|
||||
{
|
||||
return new TestPoolableObject { PoolKey = key };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化方法,用于对象池初始化时的操作
|
||||
/// </summary>
|
||||
protected override void OnInit()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用池化对象类,实现了IPoolableObject接口
|
||||
/// </summary>
|
||||
public class TestPoolableObject : IPoolableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置对象的池键
|
||||
/// </summary>
|
||||
public string PoolKey { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置测试用的整数值
|
||||
/// </summary>
|
||||
public int TestValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置OnAcquire方法是否被调用的标志
|
||||
/// </summary>
|
||||
public bool OnAcquireCalled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置OnRelease方法是否被调用的标志
|
||||
/// </summary>
|
||||
public bool OnReleaseCalled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置OnPoolDestroy方法是否被调用的标志
|
||||
/// </summary>
|
||||
public bool OnPoolDestroyCalled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 对象被获取时的回调方法
|
||||
/// </summary>
|
||||
public void OnAcquire()
|
||||
{
|
||||
OnAcquireCalled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对象被释放时的回调方法
|
||||
/// </summary>
|
||||
public void OnRelease()
|
||||
{
|
||||
OnReleaseCalled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对象被销毁时的回调方法
|
||||
/// </summary>
|
||||
public void OnPoolDestroy()
|
||||
{
|
||||
OnPoolDestroyCalled = true;
|
||||
|
||||
@ -3,15 +3,24 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.property;
|
||||
|
||||
/// <summary>
|
||||
/// BindableProperty类的单元测试
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class BindablePropertyTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试清理方法,在每个测试方法执行后重置比较器
|
||||
/// </summary>
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
BindableProperty<string>.Comparer = (a, b) => a?.Equals(b) ?? b == null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试获取值时应返回默认值
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Value_Get_Should_Return_Default_Value()
|
||||
{
|
||||
@ -20,6 +29,9 @@ public class BindablePropertyTests
|
||||
Assert.That(property.Value, Is.EqualTo(5));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试设置值时应触发事件
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Value_Set_Should_Trigger_Event()
|
||||
{
|
||||
@ -33,6 +45,9 @@ public class BindablePropertyTests
|
||||
Assert.That(receivedValue, Is.EqualTo(42));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试设置相同值时不触发事件
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Value_Set_To_Same_Value_Should_Not_Trigger_Event()
|
||||
{
|
||||
@ -46,6 +61,9 @@ public class BindablePropertyTests
|
||||
Assert.That(count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试取消注册应移除处理器
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void UnRegister_Should_Remove_Handler()
|
||||
{
|
||||
@ -63,6 +81,9 @@ public class BindablePropertyTests
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试带初始值注册应立即调用处理器
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void RegisterWithInitValue_Should_Call_Handler_Immediately()
|
||||
{
|
||||
@ -74,6 +95,9 @@ public class BindablePropertyTests
|
||||
Assert.That(receivedValue, Is.EqualTo(5));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试无事件设置值不应触发事件
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SetValueWithoutEvent_Should_Not_Trigger_Event()
|
||||
{
|
||||
@ -88,12 +112,16 @@ public class BindablePropertyTests
|
||||
Assert.That(property.Value, Is.EqualTo(42));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试使用自定义比较器
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void WithComparer_Should_Use_Custom_Comparer()
|
||||
{
|
||||
var comparerWasCalled = false;
|
||||
var comparisonResult = false;
|
||||
|
||||
// 设置自定义比较器
|
||||
BindableProperty<string>.Comparer = (a, b) =>
|
||||
{
|
||||
comparerWasCalled = true;
|
||||
@ -112,6 +140,9 @@ public class BindablePropertyTests
|
||||
Assert.That(count, Is.EqualTo(0), "不应该触发事件");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试多个处理器都应被调用
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Multiple_Handlers_Should_All_Be_Called()
|
||||
{
|
||||
@ -128,6 +159,9 @@ public class BindablePropertyTests
|
||||
Assert.That(count2, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试注册应返回IUnRegister接口
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Register_Should_Return_IUnRegister()
|
||||
{
|
||||
@ -137,6 +171,9 @@ public class BindablePropertyTests
|
||||
Assert.That(unRegister, Is.Not.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ToString应返回值的字符串表示
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ToString_Should_Return_Value_As_String()
|
||||
{
|
||||
|
||||
@ -4,9 +4,15 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.query;
|
||||
|
||||
/// <summary>
|
||||
/// 查询总线测试类,用于测试QueryBus的功能和异常处理
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class QueryBusTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试设置方法,在每个测试方法执行前初始化查询总线实例
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@ -15,6 +21,10 @@ public class QueryBusTests
|
||||
|
||||
private QueryBus _queryBus = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 测试Send方法是否能正确返回查询结果
|
||||
/// 验证当传入有效查询对象时,能够得到预期的计算结果
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Send_Should_Return_Query_Result()
|
||||
{
|
||||
@ -26,12 +36,20 @@ public class QueryBusTests
|
||||
Assert.That(result, Is.EqualTo(20));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试Send方法在传入空查询对象时是否会抛出ArgumentNullException异常
|
||||
/// 验证参数验证功能的正确性
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Send_WithNullQuery_Should_ThrowArgumentNullException()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => _queryBus.Send<int>(null!));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试Send方法是否能正确返回字符串类型的查询结果
|
||||
/// 验证不同返回类型的支持情况
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Send_WithStringResult_Should_Return_String()
|
||||
{
|
||||
@ -44,29 +62,62 @@ public class QueryBusTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用查询输入类,实现IQueryInput接口
|
||||
/// 用于传递查询所需的参数信息
|
||||
/// </summary>
|
||||
public sealed class TestQueryInput : IQueryInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置查询值
|
||||
/// </summary>
|
||||
public int Value { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 整数类型测试查询类,继承自AbstractQuery
|
||||
/// 实现具体的查询逻辑并返回整数结果
|
||||
/// </summary>
|
||||
public sealed class TestQuery : AbstractQuery<TestQueryInput, int>
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化TestQuery的新实例
|
||||
/// </summary>
|
||||
/// <param name="input">查询输入参数</param>
|
||||
public TestQuery(TestQueryInput input) : base(input)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行查询操作的具体实现
|
||||
/// </summary>
|
||||
/// <param name="input">查询输入参数</param>
|
||||
/// <returns>查询结果,将输入值乘以2</returns>
|
||||
protected override int OnDo(TestQueryInput input)
|
||||
{
|
||||
return input.Value * 2;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字符串类型测试查询类,继承自AbstractQuery
|
||||
/// 实现具体的查询逻辑并返回字符串结果
|
||||
/// </summary>
|
||||
public sealed class TestStringQuery : AbstractQuery<TestQueryInput, string>
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化TestStringQuery的新实例
|
||||
/// </summary>
|
||||
/// <param name="input">查询输入参数</param>
|
||||
public TestStringQuery(TestQueryInput input) : base(input)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行查询操作的具体实现
|
||||
/// </summary>
|
||||
/// <param name="input">查询输入参数</param>
|
||||
/// <returns>格式化的字符串结果</returns>
|
||||
protected override string OnDo(TestQueryInput input)
|
||||
{
|
||||
return $"Result: {input.Value * 2}";
|
||||
|
||||
@ -7,9 +7,17 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.rule;
|
||||
|
||||
/// <summary>
|
||||
/// 测试 ContextAware 功能的单元测试类
|
||||
/// 验证上下文感知对象的设置、获取和回调功能
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class ContextAwareTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 在每个测试方法执行前进行初始化设置
|
||||
/// 创建测试用的 ContextAware 对象和模拟上下文,并绑定到游戏上下文中
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@ -18,6 +26,10 @@ public class ContextAwareTests
|
||||
GameContext.Bind(typeof(TestArchitectureContext), _mockContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在每个测试方法执行后进行清理工作
|
||||
/// 从游戏上下文中解绑测试用的架构上下文类型
|
||||
/// </summary>
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
@ -27,6 +39,10 @@ public class ContextAwareTests
|
||||
private TestContextAware _contextAware = null!;
|
||||
private TestArchitectureContext _mockContext = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 测试 SetContext 方法是否正确设置上下文属性
|
||||
/// 验证通过 IContextAware 接口设置上下文后,内部的 PublicContext 属性能够正确返回设置的上下文
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SetContext_Should_Set_Context_Property()
|
||||
{
|
||||
@ -36,6 +52,10 @@ public class ContextAwareTests
|
||||
Assert.That(_contextAware.PublicContext, Is.SameAs(_mockContext));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试 SetContext 方法是否正确调用 OnContextReady 回调方法
|
||||
/// 验证设置上下文后,OnContextReady 方法被正确触发
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SetContext_Should_Call_OnContextReady()
|
||||
{
|
||||
@ -45,6 +65,10 @@ public class ContextAwareTests
|
||||
Assert.That(_contextAware.OnContextReadyCalled, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试 GetContext 方法是否返回已设置的上下文
|
||||
/// 验证通过 IContextAware 接口设置上下文后,GetContext 方法能正确返回相同的上下文实例
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetContext_Should_Return_Set_Context()
|
||||
{
|
||||
@ -56,6 +80,11 @@ public class ContextAwareTests
|
||||
Assert.That(result, Is.SameAs(_mockContext));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试 GetContext 方法在未设置上下文时的行为
|
||||
/// 验证当内部 Context 为 null 时,GetContext 方法不会抛出异常
|
||||
/// 此时应返回第一个架构上下文(在测试环境中验证不抛出异常即可)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetContext_Should_Return_FirstArchitectureContext_When_Not_Set()
|
||||
{
|
||||
@ -72,11 +101,26 @@ public class ContextAwareTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用于测试的 ContextAware 实现类
|
||||
/// 继承自 ContextAwareBase,提供公共访问的上下文属性和回调状态跟踪
|
||||
/// </summary>
|
||||
public class TestContextAware : ContextAwareBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取内部上下文的公共访问属性
|
||||
/// </summary>
|
||||
public IArchitectureContext? PublicContext => Context;
|
||||
|
||||
/// <summary>
|
||||
/// 跟踪 OnContextReady 方法是否被调用的状态
|
||||
/// </summary>
|
||||
public bool OnContextReadyCalled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 重写上下文就绪回调方法
|
||||
/// 设置 OnContextReadyCalled 标志为 true,用于测试验证
|
||||
/// </summary>
|
||||
protected override void OnContextReady()
|
||||
{
|
||||
OnContextReadyCalled = true;
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
using GFramework.Core.Abstractions.architecture;
|
||||
using GFramework.Core.Abstractions.enums;
|
||||
using GFramework.Core.Abstractions.state;
|
||||
using GFramework.Core.Abstractions.system;
|
||||
@ -13,13 +12,26 @@ using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.state;
|
||||
|
||||
/// <summary>
|
||||
/// ContextAwareStateMachine类的单元测试
|
||||
/// 测试内容包括:
|
||||
/// - 作为ISystem的集成测试
|
||||
/// - Init方法 - 初始化上下文感知状态
|
||||
/// - Init方法 - 设置Context属性
|
||||
/// - Destroy方法 - 清理状态
|
||||
/// - OnArchitecturePhase方法 - 接收架构阶段
|
||||
/// - 上下文感知状态初始化
|
||||
/// - 状态变更事件发送
|
||||
/// - SetContext方法
|
||||
/// - GetContext方法
|
||||
/// - ISystem接口实现验证
|
||||
/// - 与EventBus的集成测试
|
||||
/// - 多状态注册和切换
|
||||
/// - 状态机生命周期完整性
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class ContextAwareStateMachineTests
|
||||
{
|
||||
private TestContextAwareStateMachineV5? _stateMachine;
|
||||
private ArchitectureContext? _context;
|
||||
private EventBus? _eventBus;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@ -30,216 +42,312 @@ public class ContextAwareStateMachineTests
|
||||
new CommandBus(),
|
||||
new QueryBus(),
|
||||
new DefaultEnvironment());
|
||||
|
||||
|
||||
_stateMachine = new TestContextAwareStateMachineV5();
|
||||
_stateMachine.SetContext(_context);
|
||||
}
|
||||
|
||||
private TestContextAwareStateMachineV5? _stateMachine;
|
||||
private ArchitectureContext? _context;
|
||||
private EventBus? _eventBus;
|
||||
|
||||
/// <summary>
|
||||
/// 测试ContextAwareStateMachine实现ISystem接口
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ContextAwareStateMachine_Should_Implement_ISystem_Interface()
|
||||
{
|
||||
Assert.That(_stateMachine, Is.InstanceOf<ISystem>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试SetContext设置Context属性
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SetContext_Should_Set_Context_Property()
|
||||
{
|
||||
_stateMachine!.SetContext(_context!);
|
||||
|
||||
|
||||
var context = _stateMachine.GetContext();
|
||||
Assert.That(context, Is.SameAs(_context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试GetContext返回Context属性
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetContext_Should_Return_Context_Property()
|
||||
{
|
||||
_stateMachine!.SetContext(_context!);
|
||||
|
||||
|
||||
var context = _stateMachine.GetContext();
|
||||
Assert.That(context, Is.Not.Null);
|
||||
Assert.That(context, Is.SameAs(_context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试Init方法为所有ContextAware状态设置Context
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Init_Should_SetContext_On_All_ContextAware_States()
|
||||
{
|
||||
var state1 = new TestContextAwareStateV5();
|
||||
var state2 = new TestContextAwareStateV5_2();
|
||||
|
||||
|
||||
_stateMachine!.Register(state1);
|
||||
_stateMachine.Register(state2);
|
||||
|
||||
|
||||
Assert.That(state1.GetContext(), Is.Null);
|
||||
Assert.That(state2.GetContext(), Is.Null);
|
||||
|
||||
|
||||
_stateMachine.Init();
|
||||
|
||||
|
||||
Assert.That(state1.GetContext(), Is.SameAs(_context));
|
||||
Assert.That(state2.GetContext(), Is.SameAs(_context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试Init方法不为非ContextAware状态设置Context
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Init_Should_Not_SetContext_On_NonContextAware_States()
|
||||
{
|
||||
var state = new TestStateV5();
|
||||
|
||||
|
||||
_stateMachine!.Register(state);
|
||||
_stateMachine.Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试Destroy方法不抛出异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Destroy_Should_Not_Throw_Exception()
|
||||
{
|
||||
Assert.That(() => _stateMachine!.Destroy(), Throws.Nothing);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试OnArchitecturePhase方法不抛出异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void OnArchitecturePhase_Should_Not_Throw_Exception()
|
||||
{
|
||||
Assert.That(() => _stateMachine!.OnArchitecturePhase(ArchitecturePhase.Ready),
|
||||
Assert.That(() => _stateMachine!.OnArchitecturePhase(ArchitecturePhase.Ready),
|
||||
Throws.Nothing);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ChangeTo发送StateChangedEvent事件
|
||||
/// 验证当状态机切换到新状态时,会正确触发StateChangedEvent事件,并且事件中的旧状态为null(首次切换)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ChangeTo_Should_Send_StateChangedEvent()
|
||||
{
|
||||
// 订阅StateChangedEvent事件以验证事件是否被正确发送
|
||||
bool eventReceived = false;
|
||||
StateChangedEvent? receivedEvent = null;
|
||||
|
||||
|
||||
_eventBus!.Register<StateChangedEvent>(e =>
|
||||
{
|
||||
eventReceived = true;
|
||||
receivedEvent = e;
|
||||
});
|
||||
|
||||
|
||||
var state1 = new TestStateV5();
|
||||
var state2 = new TestStateV5();
|
||||
|
||||
|
||||
_stateMachine!.Register(state1);
|
||||
_stateMachine.Register(state2);
|
||||
|
||||
|
||||
_stateMachine.Init();
|
||||
_stateMachine.ChangeTo<TestStateV5>();
|
||||
|
||||
|
||||
Assert.That(eventReceived, Is.True);
|
||||
Assert.That(receivedEvent!.OldState, Is.Null);
|
||||
Assert.That(receivedEvent.NewState, Is.InstanceOf<TestStateV5>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试ChangeTo发送StateChangedEvent事件(包含旧状态)
|
||||
/// 验证当状态机从一个状态切换到另一个状态时,会正确触发StateChangedEvent事件,
|
||||
/// 并且事件中包含正确的旧状态和新状态信息
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ChangeTo_Should_Send_StateChangedEvent_With_OldState()
|
||||
{
|
||||
// 订阅StateChangedEvent事件以验证事件是否被正确发送
|
||||
bool eventReceived = false;
|
||||
StateChangedEvent? receivedEvent = null;
|
||||
|
||||
|
||||
_eventBus!.Register<StateChangedEvent>(e =>
|
||||
{
|
||||
eventReceived = true;
|
||||
receivedEvent = e;
|
||||
});
|
||||
|
||||
|
||||
var state1 = new TestStateV5();
|
||||
var state2 = new TestStateV5();
|
||||
|
||||
|
||||
_stateMachine!.Register(state1);
|
||||
_stateMachine.Register(state2);
|
||||
|
||||
|
||||
_stateMachine.Init();
|
||||
_stateMachine.ChangeTo<TestStateV5>();
|
||||
_stateMachine.ChangeTo<TestStateV5>();
|
||||
|
||||
|
||||
Assert.That(eventReceived, Is.True);
|
||||
Assert.That(receivedEvent!.OldState, Is.InstanceOf<TestStateV5>());
|
||||
Assert.That(receivedEvent.NewState, Is.InstanceOf<TestStateV5>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试CanChangeTo方法对于已注册状态的工作情况
|
||||
/// 验证当状态已注册到状态机中时,CanChangeTo方法应返回true
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void CanChangeTo_Should_Work_With_Registered_States()
|
||||
{
|
||||
var state = new TestStateV5();
|
||||
|
||||
|
||||
_stateMachine!.Register(state);
|
||||
|
||||
|
||||
var canChange = _stateMachine.CanChangeTo<TestStateV5>();
|
||||
Assert.That(canChange, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试可以注册多个状态
|
||||
/// 验证状态机能够成功注册多个不同的状态实例,并且能够切换到这些已注册的状态
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Multiple_States_Should_Be_Registered()
|
||||
{
|
||||
var state1 = new TestStateV5 { Id = 1 };
|
||||
var state2 = new TestStateV5 { Id = 2 };
|
||||
var state3 = new TestStateV5 { Id = 3 };
|
||||
|
||||
|
||||
_stateMachine!.Register(state1);
|
||||
_stateMachine.Register(state2);
|
||||
_stateMachine.Register(state3);
|
||||
|
||||
|
||||
var canChange = _stateMachine.CanChangeTo<TestStateV5>();
|
||||
Assert.That(canChange, Is.True);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 测试状态机生命周期完整
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void StateMachine_Lifecycle_Should_Be_Complete()
|
||||
{
|
||||
var state1 = new TestStateV5();
|
||||
var state2 = new TestStateV5();
|
||||
|
||||
|
||||
_stateMachine!.Register(state1);
|
||||
_stateMachine.Register(state2);
|
||||
|
||||
|
||||
_stateMachine.Init();
|
||||
Assert.That(_stateMachine.Current, Is.Null);
|
||||
|
||||
|
||||
_stateMachine.ChangeTo<TestStateV5>();
|
||||
Assert.That(_stateMachine.Current, Is.InstanceOf<TestStateV5>());
|
||||
|
||||
|
||||
_stateMachine.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
#region Test Classes
|
||||
|
||||
/// <summary>
|
||||
/// 测试用的ContextAwareStateMachine派生类,用于访问内部状态字典
|
||||
/// </summary>
|
||||
public class TestContextAwareStateMachineV5 : ContextAwareStateMachine
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取状态机内部的状态字典
|
||||
/// </summary>
|
||||
/// <returns>类型到状态实例的映射字典</returns>
|
||||
public Dictionary<Type, IState> GetStates() => States;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用的上下文感知状态基类实现
|
||||
/// </summary>
|
||||
public class TestContextAwareStateV5 : ContextAwareStateBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 进入状态时调用
|
||||
/// </summary>
|
||||
/// <param name="previous">前一个状态</param>
|
||||
public override void OnEnter(IState? previous)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出状态时调用
|
||||
/// </summary>
|
||||
/// <param name="next">下一个状态</param>
|
||||
public override void OnExit(IState? next)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 第二个测试用的上下文感知状态基类实现
|
||||
/// </summary>
|
||||
public class TestContextAwareStateV5_2 : ContextAwareStateBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 进入状态时调用
|
||||
/// </summary>
|
||||
/// <param name="previous">前一个状态</param>
|
||||
public override void OnEnter(IState? previous)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出状态时调用
|
||||
/// </summary>
|
||||
/// <param name="next">下一个状态</param>
|
||||
public override void OnExit(IState? next)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试用的普通状态实现
|
||||
/// </summary>
|
||||
public class TestStateV5 : IState
|
||||
{
|
||||
/// <summary>
|
||||
/// 状态标识符
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否可以转换到指定状态
|
||||
/// </summary>
|
||||
/// <param name="next">目标状态</param>
|
||||
/// <returns>始终返回true表示允许转换</returns>
|
||||
public bool CanTransitionTo(IState next) => true;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 进入状态时调用
|
||||
/// </summary>
|
||||
/// <param name="previous">前一个状态</param>
|
||||
public void OnEnter(IState? previous)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出状态时调用
|
||||
/// </summary>
|
||||
/// <param name="next">下一个状态</param>
|
||||
public void OnExit(IState? next)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
@ -1,12 +1,19 @@
|
||||
using System.Reflection;
|
||||
using GFramework.Core.Abstractions.state;
|
||||
using GFramework.Core.state;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.state;
|
||||
|
||||
/// <summary>
|
||||
/// 测试状态机功能的单元测试类
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class StateMachineTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 在每个测试方法执行前初始化状态机实例
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@ -15,12 +22,18 @@ public class StateMachineTests
|
||||
|
||||
private StateMachine _stateMachine = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 验证当没有活动状态时,当前状态应为null
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Current_Should_BeNull_When_NoState_Active()
|
||||
{
|
||||
Assert.That(_stateMachine.Current, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证注册状态后,状态会被添加到状态字典中
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Register_Should_AddState_To_StatesDictionary()
|
||||
{
|
||||
@ -30,6 +43,9 @@ public class StateMachineTests
|
||||
Assert.That(_stateMachine.ContainsState<TestStateV2>(), Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证ChangeTo方法能够正确设置当前状态
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ChangeTo_Should_SetCurrentState()
|
||||
{
|
||||
@ -40,6 +56,9 @@ public class StateMachineTests
|
||||
Assert.That(_stateMachine.Current, Is.SameAs(state));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证ChangeTo方法会调用OnEnter回调
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ChangeTo_Should_Invoke_OnEnter()
|
||||
{
|
||||
@ -51,6 +70,9 @@ public class StateMachineTests
|
||||
Assert.That(state.EnterFrom, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当存在当前状态时,切换到新状态会调用原状态的OnExit回调
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ChangeTo_When_CurrentStateExists_Should_Invoke_OnExit()
|
||||
{
|
||||
@ -66,6 +88,9 @@ public class StateMachineTests
|
||||
Assert.That(state1.ExitTo, Is.SameAs(state2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当存在当前状态时,切换到新状态会调用新状态的OnEnter回调
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ChangeTo_When_CurrentStateExists_Should_Invoke_OnEnter()
|
||||
{
|
||||
@ -81,6 +106,9 @@ public class StateMachineTests
|
||||
Assert.That(state2.EnterFrom, Is.SameAs(state1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证切换到相同状态时不应调用回调方法
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ChangeTo_ToSameState_Should_NotInvoke_Callbacks()
|
||||
{
|
||||
@ -97,12 +125,18 @@ public class StateMachineTests
|
||||
Assert.That(state.ExitCallCount, Is.EqualTo(exitCount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证切换到未注册状态时应抛出InvalidOperationException异常
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ChangeTo_ToUnregisteredState_Should_ThrowInvalidOperationException()
|
||||
{
|
||||
Assert.Throws<InvalidOperationException>(() => _stateMachine.ChangeTo<TestStateV2>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当状态未注册时CanChangeTo方法应返回false
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void CanChangeTo_WhenStateNotRegistered_Should_ReturnFalse()
|
||||
{
|
||||
@ -110,6 +144,9 @@ public class StateMachineTests
|
||||
Assert.That(result, Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当状态已注册时CanChangeTo方法应返回true
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void CanChangeTo_WhenStateRegistered_Should_ReturnTrue()
|
||||
{
|
||||
@ -120,6 +157,9 @@ public class StateMachineTests
|
||||
Assert.That(result, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当当前状态拒绝转换时CanChangeTo方法应返回false
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void CanChangeTo_WhenCurrentStateDeniesTransition_Should_ReturnFalse()
|
||||
{
|
||||
@ -133,6 +173,9 @@ public class StateMachineTests
|
||||
Assert.That(result, Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当当前状态拒绝转换时不应发生状态变化
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ChangeTo_WhenCurrentStateDeniesTransition_Should_NotChange()
|
||||
{
|
||||
@ -150,6 +193,9 @@ public class StateMachineTests
|
||||
Assert.That(state2.EnterCalled, Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证注销状态后应从字典中移除该状态
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Unregister_Should_RemoveState_FromDictionary()
|
||||
{
|
||||
@ -160,6 +206,9 @@ public class StateMachineTests
|
||||
Assert.That(_stateMachine.ContainsState<TestStateV2>(), Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当活动状态被注销时应调用OnExit并清除当前状态
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Unregister_WhenStateIsActive_Should_Invoke_OnExit_AndClearCurrent()
|
||||
{
|
||||
@ -173,6 +222,9 @@ public class StateMachineTests
|
||||
Assert.That(_stateMachine.Current, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当非活动状态被注销时不应调用OnExit
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Unregister_WhenStateNotActive_Should_Not_Invoke_OnExit()
|
||||
{
|
||||
@ -188,6 +240,9 @@ public class StateMachineTests
|
||||
Assert.That(_stateMachine.Current, Is.SameAs(state1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证多次状态转换应正确调用回调方法
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void MultipleStateChanges_Should_Invoke_Callbacks_Correctly()
|
||||
{
|
||||
@ -210,6 +265,9 @@ public class StateMachineTests
|
||||
Assert.That(state3.ExitCalled, Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证ChangeTo方法应遵循CanTransitionTo逻辑
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ChangeTo_Should_Respect_CanTransitionTo_Logic()
|
||||
{
|
||||
@ -229,6 +287,9 @@ public class StateMachineTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试状态类V2版本,实现IState接口用于测试
|
||||
/// </summary>
|
||||
public sealed class TestStateV2 : IState
|
||||
{
|
||||
public bool AllowTransition { get; set; } = true;
|
||||
@ -239,6 +300,10 @@ public sealed class TestStateV2 : IState
|
||||
public IState? EnterFrom { get; private set; }
|
||||
public IState? ExitTo { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进入状态时的回调方法
|
||||
/// </summary>
|
||||
/// <param name="from">从哪个状态进入</param>
|
||||
public void OnEnter(IState? from)
|
||||
{
|
||||
EnterCalled = true;
|
||||
@ -246,6 +311,10 @@ public sealed class TestStateV2 : IState
|
||||
EnterFrom = from;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 离开状态时的回调方法
|
||||
/// </summary>
|
||||
/// <param name="to">离开到哪个状态</param>
|
||||
public void OnExit(IState? to)
|
||||
{
|
||||
ExitCalled = true;
|
||||
@ -253,12 +322,20 @@ public sealed class TestStateV2 : IState
|
||||
ExitTo = to;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否可以转换到目标状态
|
||||
/// </summary>
|
||||
/// <param name="target">目标状态</param>
|
||||
/// <returns>是否允许转换</returns>
|
||||
public bool CanTransitionTo(IState target)
|
||||
{
|
||||
return AllowTransition;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试状态类V3版本,实现IState接口用于测试
|
||||
/// </summary>
|
||||
public sealed class TestStateV3 : IState
|
||||
{
|
||||
public bool EnterCalled { get; private set; }
|
||||
@ -268,6 +345,10 @@ public sealed class TestStateV3 : IState
|
||||
public IState? EnterFrom { get; private set; }
|
||||
public IState? ExitTo { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进入状态时的回调方法
|
||||
/// </summary>
|
||||
/// <param name="from">从哪个状态进入</param>
|
||||
public void OnEnter(IState? from)
|
||||
{
|
||||
EnterCalled = true;
|
||||
@ -275,6 +356,10 @@ public sealed class TestStateV3 : IState
|
||||
EnterFrom = from;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 离开状态时的回调方法
|
||||
/// </summary>
|
||||
/// <param name="to">离开到哪个状态</param>
|
||||
public void OnExit(IState? to)
|
||||
{
|
||||
ExitCalled = true;
|
||||
@ -282,12 +367,20 @@ public sealed class TestStateV3 : IState
|
||||
ExitTo = to;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否可以转换到目标状态
|
||||
/// </summary>
|
||||
/// <param name="target">目标状态</param>
|
||||
/// <returns>是否允许转换</returns>
|
||||
public bool CanTransitionTo(IState target)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试状态类V4版本,实现IState接口用于测试
|
||||
/// </summary>
|
||||
public sealed class TestStateV4 : IState
|
||||
{
|
||||
public bool EnterCalled { get; private set; }
|
||||
@ -297,6 +390,10 @@ public sealed class TestStateV4 : IState
|
||||
public IState? EnterFrom { get; private set; }
|
||||
public IState? ExitTo { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进入状态时的回调方法
|
||||
/// </summary>
|
||||
/// <param name="from">从哪个状态进入</param>
|
||||
public void OnEnter(IState? from)
|
||||
{
|
||||
EnterCalled = true;
|
||||
@ -304,6 +401,10 @@ public sealed class TestStateV4 : IState
|
||||
EnterFrom = from;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 离开状态时的回调方法
|
||||
/// </summary>
|
||||
/// <param name="to">离开到哪个状态</param>
|
||||
public void OnExit(IState? to)
|
||||
{
|
||||
ExitCalled = true;
|
||||
@ -311,18 +412,32 @@ public sealed class TestStateV4 : IState
|
||||
ExitTo = to;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否可以转换到目标状态
|
||||
/// </summary>
|
||||
/// <param name="target">目标状态</param>
|
||||
/// <returns>是否允许转换</returns>
|
||||
public bool CanTransitionTo(IState target)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 状态机扩展方法类
|
||||
/// </summary>
|
||||
public static class StateMachineExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 检查状态机是否包含指定类型的状态
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要检查的状态类型</typeparam>
|
||||
/// <param name="stateMachine">状态机实例</param>
|
||||
/// <returns>如果包含指定类型的状态则返回true,否则返回false</returns>
|
||||
public static bool ContainsState<T>(this StateMachine stateMachine) where T : IState
|
||||
{
|
||||
return stateMachine.GetType().GetField("States", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?
|
||||
.GetValue(stateMachine) is System.Collections.Generic.Dictionary<System.Type, IState> states &&
|
||||
return stateMachine.GetType().GetField("States", BindingFlags.NonPublic | BindingFlags.Instance)?
|
||||
.GetValue(stateMachine) is Dictionary<Type, IState> states &&
|
||||
states.ContainsKey(typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,17 @@
|
||||
using GFramework.Core.Abstractions.state;
|
||||
using GFramework.Core.state;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.state;
|
||||
|
||||
/// <summary>
|
||||
/// 测试状态模式实现的功能和行为
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class StateTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证状态类是否正确实现了IState接口
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void State_Should_Implement_IState_Interface()
|
||||
{
|
||||
@ -15,6 +20,9 @@ public class StateTests
|
||||
Assert.That(state is IState);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证进入状态时OnEnter方法被正确调用并记录来源状态
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void OnEnter_Should_BeCalled_When_State_Enters()
|
||||
{
|
||||
@ -27,6 +35,9 @@ public class StateTests
|
||||
Assert.That(state.EnterFrom, Is.SameAs(otherState));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当传入null作为来源状态时的处理情况
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void OnEnter_WithNull_Should_Set_EnterFrom_ToNull()
|
||||
{
|
||||
@ -38,6 +49,9 @@ public class StateTests
|
||||
Assert.That(state.EnterFrom, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证退出状态时OnExit方法被正确调用并记录目标状态
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void OnExit_Should_BeCalled_When_State_Exits()
|
||||
{
|
||||
@ -50,6 +64,9 @@ public class StateTests
|
||||
Assert.That(state.ExitTo, Is.SameAs(otherState));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证当传入null作为目标状态时的处理情况
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void OnExit_WithNull_Should_Set_ExitTo_ToNull()
|
||||
{
|
||||
@ -61,6 +78,9 @@ public class StateTests
|
||||
Assert.That(state.ExitTo, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证允许转换时CanTransitionTo方法返回true
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void CanTransitionTo_WithAllowTrue_Should_ReturnTrue()
|
||||
{
|
||||
@ -72,6 +92,9 @@ public class StateTests
|
||||
Assert.That(result, Is.True);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证不允许转换时CanTransitionTo方法返回false
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void CanTransitionTo_WithAllowFalse_Should_ReturnFalse()
|
||||
{
|
||||
@ -83,6 +106,9 @@ public class StateTests
|
||||
Assert.That(result, Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证CanTransitionTo方法正确接收目标状态参数
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void CanTransitionTo_Should_Receive_TargetState()
|
||||
{
|
||||
@ -96,6 +122,9 @@ public class StateTests
|
||||
Assert.That(receivedTarget, Is.SameAs(target));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证具有复杂转换规则的状态类功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void State_WithComplexTransitionRules_Should_Work()
|
||||
{
|
||||
@ -107,6 +136,9 @@ public class StateTests
|
||||
Assert.That(state1.CanTransitionTo(state3), Is.False);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证多个状态之间的协作功能
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void MultipleStates_Should_WorkTogether()
|
||||
{
|
||||
@ -126,6 +158,9 @@ public class StateTests
|
||||
Assert.That(state3.EnterFrom, Is.SameAs(state2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证状态对多次转换的跟踪能力
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void State_Should_Track_MultipleTransitions()
|
||||
{
|
||||
@ -141,6 +176,9 @@ public class StateTests
|
||||
Assert.That(state.ExitCallCount, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证相同类型状态间的转换处理
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void State_Should_Handle_SameState_Transition()
|
||||
{
|
||||
@ -158,27 +196,66 @@ public class StateTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 具体状态实现类V2版本,用于测试状态的基本功能
|
||||
/// </summary>
|
||||
public sealed class ConcreteStateV2 : IState
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置是否允许转换
|
||||
/// </summary>
|
||||
public bool AllowTransitions { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 获取进入状态是否被调用的标志
|
||||
/// </summary>
|
||||
public bool EnterCalled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取退出状态是否被调用的标志
|
||||
/// </summary>
|
||||
public bool ExitCalled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取进入此状态的来源状态
|
||||
/// </summary>
|
||||
public IState? EnterFrom { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取从此状态退出的目标状态
|
||||
/// </summary>
|
||||
public IState? ExitTo { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置转换到目标状态时执行的动作
|
||||
/// </summary>
|
||||
public Action<IState>? CanTransitionToAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进入当前状态时调用的方法
|
||||
/// </summary>
|
||||
/// <param name="from">从哪个状态进入</param>
|
||||
public void OnEnter(IState? from)
|
||||
{
|
||||
EnterCalled = true;
|
||||
EnterFrom = from;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出当前状态时调用的方法
|
||||
/// </summary>
|
||||
/// <param name="to">退出到哪个状态</param>
|
||||
public void OnExit(IState? to)
|
||||
{
|
||||
ExitCalled = true;
|
||||
ExitTo = to;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否可以转换到目标状态
|
||||
/// </summary>
|
||||
/// <param name="target">目标状态</param>
|
||||
/// <returns>如果可以转换则返回true,否则返回false</returns>
|
||||
public bool CanTransitionTo(IState target)
|
||||
{
|
||||
CanTransitionToAction?.Invoke(target);
|
||||
@ -186,103 +263,231 @@ public sealed class ConcreteStateV2 : IState
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 具体状态实现类V3版本,用于测试状态的基本功能
|
||||
/// </summary>
|
||||
public sealed class ConcreteStateV3 : IState
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取进入状态是否被调用的标志
|
||||
/// </summary>
|
||||
public bool EnterCalled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取退出状态是否被调用的标志
|
||||
/// </summary>
|
||||
public bool ExitCalled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取进入此状态的来源状态
|
||||
/// </summary>
|
||||
public IState? EnterFrom { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取从此状态退出的目标状态
|
||||
/// </summary>
|
||||
public IState? ExitTo { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进入当前状态时调用的方法
|
||||
/// </summary>
|
||||
/// <param name="from">从哪个状态进入</param>
|
||||
public void OnEnter(IState? from)
|
||||
{
|
||||
EnterCalled = true;
|
||||
EnterFrom = from;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出当前状态时调用的方法
|
||||
/// </summary>
|
||||
/// <param name="to">退出到哪个状态</param>
|
||||
public void OnExit(IState? to)
|
||||
{
|
||||
ExitCalled = true;
|
||||
ExitTo = to;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否可以转换到目标状态
|
||||
/// </summary>
|
||||
/// <param name="target">目标状态</param>
|
||||
/// <returns>如果可以转换则返回true,否则返回false</returns>
|
||||
public bool CanTransitionTo(IState target)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 具体状态实现类V4版本,用于测试状态的基本功能
|
||||
/// </summary>
|
||||
public sealed class ConcreteStateV4 : IState
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取进入状态是否被调用的标志
|
||||
/// </summary>
|
||||
public bool EnterCalled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取退出状态是否被调用的标志
|
||||
/// </summary>
|
||||
public bool ExitCalled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取进入此状态的来源状态
|
||||
/// </summary>
|
||||
public IState? EnterFrom { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取从此状态退出的目标状态
|
||||
/// </summary>
|
||||
public IState? ExitTo { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进入当前状态时调用的方法
|
||||
/// </summary>
|
||||
/// <param name="from">从哪个状态进入</param>
|
||||
public void OnEnter(IState? from)
|
||||
{
|
||||
EnterCalled = true;
|
||||
EnterFrom = from;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出当前状态时调用的方法
|
||||
/// </summary>
|
||||
/// <param name="to">退出到哪个状态</param>
|
||||
public void OnExit(IState? to)
|
||||
{
|
||||
ExitCalled = true;
|
||||
ExitTo = to;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否可以转换到目标状态
|
||||
/// </summary>
|
||||
/// <param name="target">目标状态</param>
|
||||
/// <returns>如果可以转换则返回true,否则返回false</returns>
|
||||
public bool CanTransitionTo(IState target)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 条件状态实现类V2版本,支持基于类型的条件转换规则
|
||||
/// </summary>
|
||||
public sealed class ConditionalStateV2 : IState
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置允许转换到的状态类型数组
|
||||
/// </summary>
|
||||
public Type[] AllowedTransitions { get; set; } = Array.Empty<Type>();
|
||||
|
||||
/// <summary>
|
||||
/// 获取进入状态是否被调用的标志
|
||||
/// </summary>
|
||||
public bool EnterCalled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取退出状态是否被调用的标志
|
||||
/// </summary>
|
||||
public bool ExitCalled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取进入此状态的来源状态
|
||||
/// </summary>
|
||||
public IState? EnterFrom { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取从此状态退出的目标状态
|
||||
/// </summary>
|
||||
public IState? ExitTo { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进入当前状态时调用的方法
|
||||
/// </summary>
|
||||
/// <param name="from">从哪个状态进入</param>
|
||||
public void OnEnter(IState? from)
|
||||
{
|
||||
EnterCalled = true;
|
||||
EnterFrom = from;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出当前状态时调用的方法
|
||||
/// </summary>
|
||||
/// <param name="to">退出到哪个状态</param>
|
||||
public void OnExit(IState? to)
|
||||
{
|
||||
ExitCalled = true;
|
||||
ExitTo = to;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否可以转换到目标状态
|
||||
/// </summary>
|
||||
/// <param name="target">目标状态</param>
|
||||
/// <returns>如果目标状态类型在允许列表中则返回true,否则返回false</returns>
|
||||
public bool CanTransitionTo(IState target)
|
||||
{
|
||||
return AllowedTransitions.Contains(target.GetType());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 跟踪状态实现类V2版本,用于跟踪状态转换次数
|
||||
/// </summary>
|
||||
public sealed class TrackingStateV2 : IState
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取进入状态被调用的次数
|
||||
/// </summary>
|
||||
public int EnterCallCount { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取退出状态被调用的次数
|
||||
/// </summary>
|
||||
public int ExitCallCount { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取进入此状态的来源状态
|
||||
/// </summary>
|
||||
public IState? EnterFrom { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取从此状态退出的目标状态
|
||||
/// </summary>
|
||||
public IState? ExitTo { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进入当前状态时调用的方法
|
||||
/// </summary>
|
||||
/// <param name="from">从哪个状态进入</param>
|
||||
public void OnEnter(IState? from)
|
||||
{
|
||||
EnterCallCount++;
|
||||
EnterFrom = from;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出当前状态时调用的方法
|
||||
/// </summary>
|
||||
/// <param name="to">退出到哪个状态</param>
|
||||
public void OnExit(IState? to)
|
||||
{
|
||||
ExitCallCount++;
|
||||
ExitTo = to;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否可以转换到目标状态
|
||||
/// </summary>
|
||||
/// <param name="target">目标状态</param>
|
||||
/// <returns>总是返回true</returns>
|
||||
public bool CanTransitionTo(IState target)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user