doc(core-tests): 添加架构配置和上下文相关单元测试添加注释

- 添加注释
- [skip ci]
This commit is contained in:
GeWuYou 2026-01-16 13:15:22 +08:00
parent 70e16724c9
commit 7246fef061
25 changed files with 1853 additions and 167 deletions

View File

@ -7,17 +7,31 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.architecture; namespace GFramework.Core.Tests.architecture;
/// <summary>
/// ArchitectureConfiguration类的单元测试
/// 测试内容包括:
/// - 构造函数默认值
/// - LoggerProperties默认配置ConsoleLoggerFactoryProvider + Info级别
/// - ArchitectureProperties默认配置AllowLateRegistration=false, StrictPhaseValidation=true
/// - 自定义配置替换
/// - LoggerProperties独立修改
/// - ArchitectureProperties独立修改
/// - IArchitectureConfiguration接口实现验证
/// </summary>
[TestFixture] [TestFixture]
public class ArchitectureConfigurationTests public class ArchitectureConfigurationTests
{ {
private ArchitectureConfiguration? _configuration;
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
_configuration = new ArchitectureConfiguration(); _configuration = new ArchitectureConfiguration();
} }
private ArchitectureConfiguration? _configuration;
/// <summary>
/// 测试构造函数是否正确初始化LoggerProperties
/// </summary>
[Test] [Test]
public void Constructor_Should_Initialize_LoggerProperties_With_Default_Values() public void Constructor_Should_Initialize_LoggerProperties_With_Default_Values()
{ {
@ -25,6 +39,9 @@ public class ArchitectureConfigurationTests
Assert.That(_configuration!.LoggerProperties, Is.Not.Null); Assert.That(_configuration!.LoggerProperties, Is.Not.Null);
} }
/// <summary>
/// 测试LoggerProperties默认使用ConsoleLoggerFactoryProvider
/// </summary>
[Test] [Test]
public void LoggerProperties_Should_Use_ConsoleLoggerFactoryProvider_By_Default() public void LoggerProperties_Should_Use_ConsoleLoggerFactoryProvider_By_Default()
{ {
@ -32,6 +49,9 @@ public class ArchitectureConfigurationTests
Is.InstanceOf<ConsoleLoggerFactoryProvider>()); Is.InstanceOf<ConsoleLoggerFactoryProvider>());
} }
/// <summary>
/// 测试LoggerProperties默认使用Info日志级别
/// </summary>
[Test] [Test]
public void LoggerProperties_Should_Use_Info_LogLevel_By_Default() public void LoggerProperties_Should_Use_Info_LogLevel_By_Default()
{ {
@ -42,6 +62,9 @@ public class ArchitectureConfigurationTests
Assert.That(consoleProvider!.MinLevel, Is.EqualTo(LogLevel.Info)); Assert.That(consoleProvider!.MinLevel, Is.EqualTo(LogLevel.Info));
} }
/// <summary>
/// 测试ArchitectureProperties的AllowLateRegistration默认为false
/// </summary>
[Test] [Test]
public void ArchitectureProperties_Should_Have_AllowLateRegistration_Set_To_False_By_Default() public void ArchitectureProperties_Should_Have_AllowLateRegistration_Set_To_False_By_Default()
{ {
@ -49,6 +72,9 @@ public class ArchitectureConfigurationTests
Is.False); Is.False);
} }
/// <summary>
/// 测试ArchitectureProperties的StrictPhaseValidation默认为true
/// </summary>
[Test] [Test]
public void ArchitectureProperties_Should_Have_StrictPhaseValidation_Set_To_True_By_Default() public void ArchitectureProperties_Should_Have_StrictPhaseValidation_Set_To_True_By_Default()
{ {
@ -56,6 +82,9 @@ public class ArchitectureConfigurationTests
Is.True); Is.True);
} }
/// <summary>
/// 测试LoggerProperties可以被自定义配置替换
/// </summary>
[Test] [Test]
public void LoggerProperties_Should_Be_Replaced_With_Custom_Configuration() public void LoggerProperties_Should_Be_Replaced_With_Custom_Configuration()
{ {
@ -75,6 +104,9 @@ public class ArchitectureConfigurationTests
Assert.That(currentProvider!.MinLevel, Is.EqualTo(LogLevel.Debug)); Assert.That(currentProvider!.MinLevel, Is.EqualTo(LogLevel.Debug));
} }
/// <summary>
/// 测试ArchitectureProperties可以被自定义配置替换
/// </summary>
[Test] [Test]
public void ArchitectureProperties_Should_Be_Replaced_With_Custom_Configuration() public void ArchitectureProperties_Should_Be_Replaced_With_Custom_Configuration()
{ {
@ -93,6 +125,9 @@ public class ArchitectureConfigurationTests
Is.False); Is.False);
} }
/// <summary>
/// 测试LoggerProperties可以独立修改
/// </summary>
[Test] [Test]
public void LoggerProperties_Should_Be_Modifiable_Independently() public void LoggerProperties_Should_Be_Modifiable_Independently()
{ {
@ -106,6 +141,9 @@ public class ArchitectureConfigurationTests
Assert.That(modifiedProvider!.MinLevel, Is.EqualTo(LogLevel.Debug)); Assert.That(modifiedProvider!.MinLevel, Is.EqualTo(LogLevel.Debug));
} }
/// <summary>
/// 测试ArchitectureProperties可以独立修改
/// </summary>
[Test] [Test]
public void ArchitectureProperties_Should_Be_Modifiable_Independently() public void ArchitectureProperties_Should_Be_Modifiable_Independently()
{ {
@ -118,12 +156,18 @@ public class ArchitectureConfigurationTests
Is.False); Is.False);
} }
/// <summary>
/// 测试ArchitectureConfiguration实现IArchitectureConfiguration接口
/// </summary>
[Test] [Test]
public void ArchitectureConfiguration_Should_Implement_IArchitectureConfiguration_Interface() public void ArchitectureConfiguration_Should_Implement_IArchitectureConfiguration_Interface()
{ {
Assert.That(_configuration, Is.InstanceOf<IArchitectureConfiguration>()); Assert.That(_configuration, Is.InstanceOf<IArchitectureConfiguration>());
} }
/// <summary>
/// 测试新实例不与其他实例共享LoggerProperties
/// </summary>
[Test] [Test]
public void New_Instance_Should_Not_Share_LoggerProperties_With_Other_Instance() public void New_Instance_Should_Not_Share_LoggerProperties_With_Other_Instance()
{ {
@ -133,6 +177,9 @@ public class ArchitectureConfigurationTests
Assert.That(config1.LoggerProperties, Is.Not.SameAs(config2.LoggerProperties)); Assert.That(config1.LoggerProperties, Is.Not.SameAs(config2.LoggerProperties));
} }
/// <summary>
/// 测试新实例不与其他实例共享ArchitectureProperties
/// </summary>
[Test] [Test]
public void New_Instance_Should_Not_Share_ArchitectureProperties_With_Other_Instance() public void New_Instance_Should_Not_Share_ArchitectureProperties_With_Other_Instance()
{ {

View File

@ -3,8 +3,6 @@ using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.command; using GFramework.Core.Abstractions.command;
using GFramework.Core.Abstractions.enums; using GFramework.Core.Abstractions.enums;
using GFramework.Core.Abstractions.environment; using GFramework.Core.Abstractions.environment;
using GFramework.Core.Abstractions.events;
using GFramework.Core.Abstractions.ioc;
using GFramework.Core.Abstractions.model; using GFramework.Core.Abstractions.model;
using GFramework.Core.Abstractions.query; using GFramework.Core.Abstractions.query;
using GFramework.Core.Abstractions.system; using GFramework.Core.Abstractions.system;
@ -20,16 +18,31 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.architecture; 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] [TestFixture]
public class ArchitectureContextTests public class ArchitectureContextTests
{ {
private ArchitectureContext? _context;
private IocContainer? _container;
private EventBus? _eventBus;
private CommandBus? _commandBus;
private QueryBus? _queryBus;
private DefaultEnvironment? _environment;
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -51,6 +64,16 @@ public class ArchitectureContextTests
_context = new ArchitectureContext(_container, _eventBus, _commandBus, _queryBus, _environment); _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] [Test]
public void Constructor_Should_NotThrow_When_AllParameters_AreValid() public void Constructor_Should_NotThrow_When_AllParameters_AreValid()
{ {
@ -58,6 +81,9 @@ public class ArchitectureContextTests
Throws.Nothing); Throws.Nothing);
} }
/// <summary>
/// 测试构造函数在Container为null时应抛出ArgumentNullException
/// </summary>
[Test] [Test]
public void Constructor_Should_ThrowArgumentNullException_When_Container_IsNull() public void Constructor_Should_ThrowArgumentNullException_When_Container_IsNull()
{ {
@ -65,6 +91,9 @@ public class ArchitectureContextTests
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("container")); Throws.ArgumentNullException.With.Property("ParamName").EqualTo("container"));
} }
/// <summary>
/// 测试构造函数在EventBus为null时应抛出ArgumentNullException
/// </summary>
[Test] [Test]
public void Constructor_Should_ThrowArgumentNullException_When_EventBus_IsNull() public void Constructor_Should_ThrowArgumentNullException_When_EventBus_IsNull()
{ {
@ -72,6 +101,9 @@ public class ArchitectureContextTests
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("eventBus")); Throws.ArgumentNullException.With.Property("ParamName").EqualTo("eventBus"));
} }
/// <summary>
/// 测试构造函数在CommandBus为null时应抛出ArgumentNullException
/// </summary>
[Test] [Test]
public void Constructor_Should_ThrowArgumentNullException_When_CommandBus_IsNull() public void Constructor_Should_ThrowArgumentNullException_When_CommandBus_IsNull()
{ {
@ -79,6 +111,9 @@ public class ArchitectureContextTests
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("commandBus")); Throws.ArgumentNullException.With.Property("ParamName").EqualTo("commandBus"));
} }
/// <summary>
/// 测试构造函数在QueryBus为null时应抛出ArgumentNullException
/// </summary>
[Test] [Test]
public void Constructor_Should_ThrowArgumentNullException_When_QueryBus_IsNull() public void Constructor_Should_ThrowArgumentNullException_When_QueryBus_IsNull()
{ {
@ -86,6 +121,9 @@ public class ArchitectureContextTests
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("queryBus")); Throws.ArgumentNullException.With.Property("ParamName").EqualTo("queryBus"));
} }
/// <summary>
/// 测试构造函数在Environment为null时应抛出ArgumentNullException
/// </summary>
[Test] [Test]
public void Constructor_Should_ThrowArgumentNullException_When_Environment_IsNull() public void Constructor_Should_ThrowArgumentNullException_When_Environment_IsNull()
{ {
@ -93,6 +131,9 @@ public class ArchitectureContextTests
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("environment")); Throws.ArgumentNullException.With.Property("ParamName").EqualTo("environment"));
} }
/// <summary>
/// 测试SendQuery方法在查询有效时返回正确结果
/// </summary>
[Test] [Test]
public void SendQuery_Should_ReturnResult_When_Query_IsValid() public void SendQuery_Should_ReturnResult_When_Query_IsValid()
{ {
@ -102,6 +143,9 @@ public class ArchitectureContextTests
Assert.That(result, Is.EqualTo(42)); Assert.That(result, Is.EqualTo(42));
} }
/// <summary>
/// 测试SendQuery方法在查询为null时应抛出ArgumentNullException
/// </summary>
[Test] [Test]
public void SendQuery_Should_ThrowArgumentNullException_When_Query_IsNull() public void SendQuery_Should_ThrowArgumentNullException_When_Query_IsNull()
{ {
@ -109,6 +153,9 @@ public class ArchitectureContextTests
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("query")); Throws.ArgumentNullException.With.Property("ParamName").EqualTo("query"));
} }
/// <summary>
/// 测试SendCommand方法在命令有效时正确执行
/// </summary>
[Test] [Test]
public void SendCommand_Should_ExecuteCommand_When_Command_IsValid() public void SendCommand_Should_ExecuteCommand_When_Command_IsValid()
{ {
@ -117,6 +164,9 @@ public class ArchitectureContextTests
Assert.That(testCommand.Executed, Is.True); Assert.That(testCommand.Executed, Is.True);
} }
/// <summary>
/// 测试SendCommand方法在命令为null时应抛出ArgumentNullException
/// </summary>
[Test] [Test]
public void SendCommand_Should_ThrowArgumentNullException_When_Command_IsNull() public void SendCommand_Should_ThrowArgumentNullException_When_Command_IsNull()
{ {
@ -124,6 +174,9 @@ public class ArchitectureContextTests
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("command")); Throws.ArgumentNullException.With.Property("ParamName").EqualTo("command"));
} }
/// <summary>
/// 测试SendCommand方法带返回值在命令有效时返回正确结果
/// </summary>
[Test] [Test]
public void SendCommand_WithResult_Should_ReturnResult_When_Command_IsValid() public void SendCommand_WithResult_Should_ReturnResult_When_Command_IsValid()
{ {
@ -133,6 +186,9 @@ public class ArchitectureContextTests
Assert.That(result, Is.EqualTo(123)); Assert.That(result, Is.EqualTo(123));
} }
/// <summary>
/// 测试SendCommand方法带返回值在命令为null时应抛出ArgumentNullException
/// </summary>
[Test] [Test]
public void SendCommand_WithResult_Should_ThrowArgumentNullException_When_Command_IsNull() public void SendCommand_WithResult_Should_ThrowArgumentNullException_When_Command_IsNull()
{ {
@ -140,6 +196,9 @@ public class ArchitectureContextTests
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("command")); Throws.ArgumentNullException.With.Property("ParamName").EqualTo("command"));
} }
/// <summary>
/// 测试SendEvent方法在事件类型有效时正确发送事件
/// </summary>
[Test] [Test]
public void SendEvent_Should_SendEvent_When_EventType_IsValid() public void SendEvent_Should_SendEvent_When_EventType_IsValid()
{ {
@ -150,6 +209,9 @@ public class ArchitectureContextTests
Assert.That(eventReceived, Is.True); Assert.That(eventReceived, Is.True);
} }
/// <summary>
/// 测试SendEvent方法带实例在事件实例有效时正确发送事件
/// </summary>
[Test] [Test]
public void SendEvent_WithInstance_Should_SendEvent_When_EventInstance_IsValid() public void SendEvent_WithInstance_Should_SendEvent_When_EventInstance_IsValid()
{ {
@ -161,6 +223,9 @@ public class ArchitectureContextTests
Assert.That(eventReceived, Is.True); Assert.That(eventReceived, Is.True);
} }
/// <summary>
/// 测试SendEvent方法带实例在事件实例为null时应抛出ArgumentNullException
/// </summary>
[Test] [Test]
public void SendEvent_WithInstance_Should_ThrowArgumentNullException_When_EventInstance_IsNull() public void SendEvent_WithInstance_Should_ThrowArgumentNullException_When_EventInstance_IsNull()
{ {
@ -168,6 +233,9 @@ public class ArchitectureContextTests
Throws.ArgumentNullException.With.Property("ParamName").EqualTo("e")); Throws.ArgumentNullException.With.Property("ParamName").EqualTo("e"));
} }
/// <summary>
/// 测试GetSystem方法在系统已注册时返回注册的系统
/// </summary>
[Test] [Test]
public void GetSystem_Should_ReturnRegisteredSystem_When_SystemIsRegistered() public void GetSystem_Should_ReturnRegisteredSystem_When_SystemIsRegistered()
{ {
@ -180,6 +248,9 @@ public class ArchitectureContextTests
Assert.That(result, Is.SameAs(testSystem)); Assert.That(result, Is.SameAs(testSystem));
} }
/// <summary>
/// 测试GetSystem方法在系统未注册时返回null
/// </summary>
[Test] [Test]
public void GetSystem_Should_ReturnNull_When_SystemIsNotRegistered() public void GetSystem_Should_ReturnNull_When_SystemIsNotRegistered()
{ {
@ -188,6 +259,9 @@ public class ArchitectureContextTests
Assert.That(result, Is.Null); Assert.That(result, Is.Null);
} }
/// <summary>
/// 测试GetModel方法在模型已注册时返回注册的模型
/// </summary>
[Test] [Test]
public void GetModel_Should_ReturnRegisteredModel_When_ModelIsRegistered() public void GetModel_Should_ReturnRegisteredModel_When_ModelIsRegistered()
{ {
@ -200,6 +274,9 @@ public class ArchitectureContextTests
Assert.That(result, Is.SameAs(testModel)); Assert.That(result, Is.SameAs(testModel));
} }
/// <summary>
/// 测试GetModel方法在模型未注册时返回null
/// </summary>
[Test] [Test]
public void GetModel_Should_ReturnNull_When_ModelIsNotRegistered() public void GetModel_Should_ReturnNull_When_ModelIsNotRegistered()
{ {
@ -208,6 +285,9 @@ public class ArchitectureContextTests
Assert.That(result, Is.Null); Assert.That(result, Is.Null);
} }
/// <summary>
/// 测试GetUtility方法在工具已注册时返回注册的工具
/// </summary>
[Test] [Test]
public void GetUtility_Should_ReturnRegisteredUtility_When_UtilityIsRegistered() public void GetUtility_Should_ReturnRegisteredUtility_When_UtilityIsRegistered()
{ {
@ -220,6 +300,9 @@ public class ArchitectureContextTests
Assert.That(result, Is.SameAs(testUtility)); Assert.That(result, Is.SameAs(testUtility));
} }
/// <summary>
/// 测试GetUtility方法在工具未注册时返回null
/// </summary>
[Test] [Test]
public void GetUtility_Should_ReturnNull_When_UtilityIsNotRegistered() public void GetUtility_Should_ReturnNull_When_UtilityIsNotRegistered()
{ {
@ -228,6 +311,9 @@ public class ArchitectureContextTests
Assert.That(result, Is.Null); Assert.That(result, Is.Null);
} }
/// <summary>
/// 测试GetEnvironment方法返回环境实例
/// </summary>
[Test] [Test]
public void GetEnvironment_Should_Return_EnvironmentInstance() public void GetEnvironment_Should_Return_EnvironmentInstance()
{ {
@ -247,9 +333,18 @@ public class TestSystemV2 : ISystem
public void SetContext(IArchitectureContext context) => _context = context; public void SetContext(IArchitectureContext context) => _context = context;
public IArchitectureContext GetContext() => _context; public IArchitectureContext GetContext() => _context;
public void Init() { }
public void Destroy() { } public void Init()
public void OnArchitecturePhase(ArchitecturePhase phase) { } {
}
public void Destroy()
{
}
public void OnArchitecturePhase(ArchitecturePhase phase)
{
}
} }
public class TestModelV2 : IModel public class TestModelV2 : IModel
@ -259,9 +354,18 @@ public class TestModelV2 : IModel
public void SetContext(IArchitectureContext context) => _context = context; public void SetContext(IArchitectureContext context) => _context = context;
public IArchitectureContext GetContext() => _context; public IArchitectureContext GetContext() => _context;
public void Init() { }
public void Destroy() { } public void Init()
public void OnArchitecturePhase(ArchitecturePhase phase) { } {
}
public void OnArchitecturePhase(ArchitecturePhase phase)
{
}
public void Destroy()
{
}
} }
public class TestUtilityV2 : IUtility public class TestUtilityV2 : IUtility
@ -271,8 +375,14 @@ public class TestUtilityV2 : IUtility
public void SetContext(IArchitectureContext context) => _context = context; public void SetContext(IArchitectureContext context) => _context = context;
public IArchitectureContext GetContext() => _context; public IArchitectureContext GetContext() => _context;
public void Init() { }
public void Destroy() { } public void Init()
{
}
public void Destroy()
{
}
} }
public class TestQueryV2 : IQuery<int> public class TestQueryV2 : IQuery<int>

View File

@ -1,4 +1,3 @@
using System;
using GFramework.Core.Abstractions.architecture; using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.command; using GFramework.Core.Abstractions.command;
using GFramework.Core.Abstractions.environment; using GFramework.Core.Abstractions.environment;
@ -18,12 +17,22 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.architecture; namespace GFramework.Core.Tests.architecture;
/// <summary>
/// ArchitectureServices类的单元测试
/// 测试内容包括:
/// - 服务容器初始化
/// - 所有服务实例创建Container, EventBus, CommandBus, QueryBus
/// - SetContext方法 - 设置上下文
/// - SetContext方法 - 重复设置上下文
/// - GetContext方法 - 获取已设置上下文
/// - GetContext方法 - 未设置上下文时返回null
/// - 上下文传播到容器
/// - IArchitectureServices接口实现验证
/// - 服务独立性验证(多个实例)
/// </summary>
[TestFixture] [TestFixture]
public class ArchitectureServicesTests public class ArchitectureServicesTests
{ {
private ArchitectureServices? _services;
private TestArchitectureContextV3? _context;
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -31,6 +40,12 @@ public class ArchitectureServicesTests
_context = new TestArchitectureContextV3(); _context = new TestArchitectureContextV3();
} }
private ArchitectureServices? _services;
private TestArchitectureContextV3? _context;
/// <summary>
/// 测试构造函数初始化所有服务
/// </summary>
[Test] [Test]
public void Constructor_Should_Initialize_AllServices() public void Constructor_Should_Initialize_AllServices()
{ {
@ -47,6 +62,9 @@ public class ArchitectureServicesTests
Assert.That(_services.Container, Is.InstanceOf<IocContainer>()); Assert.That(_services.Container, Is.InstanceOf<IocContainer>());
} }
/// <summary>
/// 测试EventBus是EventBus的实例
/// </summary>
[Test] [Test]
public void EventBus_Should_Be_Instance_Of_EventBus() public void EventBus_Should_Be_Instance_Of_EventBus()
{ {
@ -54,6 +72,9 @@ public class ArchitectureServicesTests
Assert.That(_services.EventBus, Is.InstanceOf<EventBus>()); Assert.That(_services.EventBus, Is.InstanceOf<EventBus>());
} }
/// <summary>
/// 测试CommandBus是CommandBus的实例
/// </summary>
[Test] [Test]
public void CommandBus_Should_Be_Instance_Of_CommandBus() public void CommandBus_Should_Be_Instance_Of_CommandBus()
{ {
@ -61,6 +82,9 @@ public class ArchitectureServicesTests
Assert.That(_services.CommandBus, Is.InstanceOf<CommandBus>()); Assert.That(_services.CommandBus, Is.InstanceOf<CommandBus>());
} }
/// <summary>
/// 测试QueryBus是QueryBus的实例
/// </summary>
[Test] [Test]
public void QueryBus_Should_Be_Instance_Of_QueryBus() public void QueryBus_Should_Be_Instance_Of_QueryBus()
{ {
@ -68,6 +92,9 @@ public class ArchitectureServicesTests
Assert.That(_services.QueryBus, Is.InstanceOf<QueryBus>()); Assert.That(_services.QueryBus, Is.InstanceOf<QueryBus>());
} }
/// <summary>
/// 测试SetContext设置内部Context字段
/// </summary>
[Test] [Test]
public void SetContext_Should_Set_Context_Internal_Field() public void SetContext_Should_Set_Context_Internal_Field()
{ {
@ -77,6 +104,9 @@ public class ArchitectureServicesTests
Assert.That(context, Is.SameAs(_context)); Assert.That(context, Is.SameAs(_context));
} }
/// <summary>
/// 测试SetContext将上下文传播到Container
/// </summary>
[Test] [Test]
public void SetContext_Should_Propagate_Context_To_Container() public void SetContext_Should_Propagate_Context_To_Container()
{ {
@ -86,6 +116,9 @@ public class ArchitectureServicesTests
Assert.That(containerContext, Is.SameAs(_context)); Assert.That(containerContext, Is.SameAs(_context));
} }
/// <summary>
/// 测试GetContext在SetContext后返回上下文
/// </summary>
[Test] [Test]
public void GetContext_Should_Return_Context_After_SetContext() public void GetContext_Should_Return_Context_After_SetContext()
{ {
@ -96,6 +129,9 @@ public class ArchitectureServicesTests
Assert.That(context, Is.SameAs(_context)); Assert.That(context, Is.SameAs(_context));
} }
/// <summary>
/// 测试GetContext在未设置上下文时返回null
/// </summary>
[Test] [Test]
public void GetContext_Should_ReturnNull_When_Context_Not_Set() public void GetContext_Should_ReturnNull_When_Context_Not_Set()
{ {
@ -104,6 +140,9 @@ public class ArchitectureServicesTests
Assert.That(context, Is.Null); Assert.That(context, Is.Null);
} }
/// <summary>
/// 测试SetContext替换已存在的上下文
/// </summary>
[Test] [Test]
public void SetContext_Should_Replace_Existing_Context() public void SetContext_Should_Replace_Existing_Context()
{ {
@ -117,12 +156,18 @@ public class ArchitectureServicesTests
Assert.That(context, Is.SameAs(context2)); Assert.That(context, Is.SameAs(context2));
} }
/// <summary>
/// 测试ArchitectureServices实现IArchitectureServices接口
/// </summary>
[Test] [Test]
public void ArchitectureServices_Should_Implement_IArchitectureServices_Interface() public void ArchitectureServices_Should_Implement_IArchitectureServices_Interface()
{ {
Assert.That(_services, Is.InstanceOf<IArchitectureServices>()); Assert.That(_services, Is.InstanceOf<IArchitectureServices>());
} }
/// <summary>
/// 测试多个实例有独立的Container
/// </summary>
[Test] [Test]
public void Multiple_Instances_Should_Have_Independent_Container() public void Multiple_Instances_Should_Have_Independent_Container()
{ {
@ -132,6 +177,9 @@ public class ArchitectureServicesTests
Assert.That(services1.Container, Is.Not.SameAs(services2.Container)); Assert.That(services1.Container, Is.Not.SameAs(services2.Container));
} }
/// <summary>
/// 测试多个实例有独立的EventBus
/// </summary>
[Test] [Test]
public void Multiple_Instances_Should_Have_Independent_EventBus() public void Multiple_Instances_Should_Have_Independent_EventBus()
{ {
@ -141,6 +189,9 @@ public class ArchitectureServicesTests
Assert.That(services1.EventBus, Is.Not.SameAs(services2.EventBus)); Assert.That(services1.EventBus, Is.Not.SameAs(services2.EventBus));
} }
/// <summary>
/// 测试多个实例有独立的CommandBus
/// </summary>
[Test] [Test]
public void Multiple_Instances_Should_Have_Independent_CommandBus() public void Multiple_Instances_Should_Have_Independent_CommandBus()
{ {
@ -150,6 +201,9 @@ public class ArchitectureServicesTests
Assert.That(services1.CommandBus, Is.Not.SameAs(services2.CommandBus)); Assert.That(services1.CommandBus, Is.Not.SameAs(services2.CommandBus));
} }
/// <summary>
/// 测试多个实例有独立的QueryBus
/// </summary>
[Test] [Test]
public void Multiple_Instances_Should_Have_Independent_QueryBus() public void Multiple_Instances_Should_Have_Independent_QueryBus()
{ {

View File

@ -17,21 +17,46 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.architecture; namespace GFramework.Core.Tests.architecture;
/// <summary>
/// GameContext类的单元测试
/// 测试内容包括:
/// - ArchitectureReadOnlyDictionary在启动时为空
/// - Bind方法添加上下文到字典
/// - Bind重复类型时抛出异常
/// - GetByType返回正确的上下文
/// - GetByType未找到时抛出异常
/// - Get泛型方法返回正确的上下文
/// - TryGet方法在找到时返回true
/// - TryGet方法在未找到时返回false
/// - GetFirstArchitectureContext在存在时返回
/// - GetFirstArchitectureContext为空时抛出异常
/// - Unbind移除上下文
/// - Clear移除所有上下文
/// </summary>
[TestFixture] [TestFixture]
public class GameContextTests public class GameContextTests
{ {
/// <summary>
/// 测试初始化方法在每个测试方法执行前清空GameContext
/// </summary>
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
GameContext.Clear(); GameContext.Clear();
} }
/// <summary>
/// 测试清理方法在每个测试方法执行后清空GameContext
/// </summary>
[TearDown] [TearDown]
public void TearDown() public void TearDown()
{ {
GameContext.Clear(); GameContext.Clear();
} }
/// <summary>
/// 测试ArchitectureReadOnlyDictionary在启动时返回空字典
/// </summary>
[Test] [Test]
public void ArchitectureReadOnlyDictionary_Should_Return_Empty_At_Start() public void ArchitectureReadOnlyDictionary_Should_Return_Empty_At_Start()
{ {
@ -40,6 +65,9 @@ public class GameContextTests
Assert.That(dict.Count, Is.EqualTo(0)); Assert.That(dict.Count, Is.EqualTo(0));
} }
/// <summary>
/// 测试Bind方法是否正确将上下文添加到字典中
/// </summary>
[Test] [Test]
public void Bind_Should_Add_Context_To_Dictionary() public void Bind_Should_Add_Context_To_Dictionary()
{ {
@ -50,6 +78,9 @@ public class GameContextTests
Assert.That(GameContext.ArchitectureReadOnlyDictionary.Count, Is.EqualTo(1)); Assert.That(GameContext.ArchitectureReadOnlyDictionary.Count, Is.EqualTo(1));
} }
/// <summary>
/// 测试Bind方法在绑定重复类型时是否抛出InvalidOperationException异常
/// </summary>
[Test] [Test]
public void Bind_WithDuplicateType_Should_ThrowInvalidOperationException() public void Bind_WithDuplicateType_Should_ThrowInvalidOperationException()
{ {
@ -62,6 +93,9 @@ public class GameContextTests
GameContext.Bind(typeof(TestArchitecture), context2)); GameContext.Bind(typeof(TestArchitecture), context2));
} }
/// <summary>
/// 测试GetByType方法是否返回正确的上下文
/// </summary>
[Test] [Test]
public void GetByType_Should_Return_Correct_Context() public void GetByType_Should_Return_Correct_Context()
{ {
@ -73,6 +107,9 @@ public class GameContextTests
Assert.That(result, Is.SameAs(context)); Assert.That(result, Is.SameAs(context));
} }
/// <summary>
/// 测试GetByType方法在未找到对应类型时是否抛出InvalidOperationException异常
/// </summary>
[Test] [Test]
public void GetByType_Should_Throw_When_Not_Found() public void GetByType_Should_Throw_When_Not_Found()
{ {
@ -80,6 +117,9 @@ public class GameContextTests
GameContext.GetByType(typeof(TestArchitecture))); GameContext.GetByType(typeof(TestArchitecture)));
} }
/// <summary>
/// 测试Get泛型方法是否返回正确的上下文
/// </summary>
[Test] [Test]
public void GetGeneric_Should_Return_Correct_Context() public void GetGeneric_Should_Return_Correct_Context()
{ {
@ -91,6 +131,9 @@ public class GameContextTests
Assert.That(result, Is.SameAs(context)); Assert.That(result, Is.SameAs(context));
} }
/// <summary>
/// 测试TryGet方法在找到上下文时是否返回true并正确设置输出参数
/// </summary>
[Test] [Test]
public void TryGet_Should_ReturnTrue_When_Found() public void TryGet_Should_ReturnTrue_When_Found()
{ {
@ -103,6 +146,9 @@ public class GameContextTests
Assert.That(foundContext, Is.SameAs(context)); Assert.That(foundContext, Is.SameAs(context));
} }
/// <summary>
/// 测试TryGet方法在未找到上下文时是否返回false且输出参数为null
/// </summary>
[Test] [Test]
public void TryGet_Should_ReturnFalse_When_Not_Found() public void TryGet_Should_ReturnFalse_When_Not_Found()
{ {
@ -112,6 +158,9 @@ public class GameContextTests
Assert.That(foundContext, Is.Null); Assert.That(foundContext, Is.Null);
} }
/// <summary>
/// 测试GetFirstArchitectureContext方法在存在上下文时是否返回正确的上下文
/// </summary>
[Test] [Test]
public void GetFirstArchitectureContext_Should_Return_When_Exists() public void GetFirstArchitectureContext_Should_Return_When_Exists()
{ {
@ -123,6 +172,9 @@ public class GameContextTests
Assert.That(result, Is.SameAs(context)); Assert.That(result, Is.SameAs(context));
} }
/// <summary>
/// 测试GetFirstArchitectureContext方法在没有上下文时是否抛出InvalidOperationException异常
/// </summary>
[Test] [Test]
public void GetFirstArchitectureContext_Should_Throw_When_Empty() public void GetFirstArchitectureContext_Should_Throw_When_Empty()
{ {
@ -130,6 +182,9 @@ public class GameContextTests
GameContext.GetFirstArchitectureContext()); GameContext.GetFirstArchitectureContext());
} }
/// <summary>
/// 测试Unbind方法是否正确移除指定类型的上下文
/// </summary>
[Test] [Test]
public void Unbind_Should_Remove_Context() public void Unbind_Should_Remove_Context()
{ {
@ -141,6 +196,9 @@ public class GameContextTests
Assert.That(GameContext.ArchitectureReadOnlyDictionary.Count, Is.EqualTo(0)); Assert.That(GameContext.ArchitectureReadOnlyDictionary.Count, Is.EqualTo(0));
} }
/// <summary>
/// 测试Clear方法是否正确移除所有上下文
/// </summary>
[Test] [Test]
public void Clear_Should_Remove_All_Contexts() public void Clear_Should_Remove_All_Contexts()
{ {
@ -153,46 +211,133 @@ public class GameContextTests
} }
} }
/// <summary>
/// 测试用的架构类继承自Architecture
/// </summary>
public class TestArchitecture : Architecture public class TestArchitecture : Architecture
{ {
/// <summary>
/// 初始化方法,当前为空实现
/// </summary>
protected override void Init() protected override void Init()
{ {
} }
} }
/// <summary>
/// 测试用的架构上下文类实现了IArchitectureContext接口
/// </summary>
public class TestArchitectureContext : IArchitectureContext public class TestArchitectureContext : IArchitectureContext
{ {
private readonly IocContainer _container = new(); private readonly IocContainer _container = new();
/// <summary>
/// 获取依赖注入容器
/// </summary>
public IIocContainer Container => _container; public IIocContainer Container => _container;
/// <summary>
/// 获取事件总线
/// </summary>
public IEventBus EventBus => new EventBus(); public IEventBus EventBus => new EventBus();
/// <summary>
/// 获取命令总线
/// </summary>
public ICommandBus CommandBus => new CommandBus(); public ICommandBus CommandBus => new CommandBus();
/// <summary>
/// 获取查询总线
/// </summary>
public IQueryBus QueryBus => new QueryBus(); public IQueryBus QueryBus => new QueryBus();
/// <summary>
/// 获取环境对象
/// </summary>
public IEnvironment Environment => new DefaultEnvironment(); 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>(); 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>(); 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>(); public TUtility? GetUtility<TUtility>() where TUtility : class, IUtility => _container.Get<TUtility>();
/// <summary>
/// 发送事件
/// </summary>
/// <typeparam name="TEvent">事件类型</typeparam>
public void SendEvent<TEvent>() where TEvent : new() 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 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(() => { }); 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) public void UnRegisterEvent<TEvent>(Action<TEvent> onEvent)
{ {
} }
/// <summary>
/// 发送命令
/// </summary>
/// <param name="command">命令对象</param>
public void SendCommand(ICommand command) 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!; 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!; public TResult SendQuery<TResult>(IQuery<TResult> query) => default!;
/// <summary>
/// 获取环境对象
/// </summary>
/// <returns>环境对象</returns>
public IEnvironment GetEnvironment() => Environment; public IEnvironment GetEnvironment() => Environment;
} }

View File

@ -4,6 +4,14 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.command; namespace GFramework.Core.Tests.command;
/// <summary>
/// CommandBus类的单元测试
/// 测试内容包括:
/// - Send方法执行命令
/// - Send方法处理null命令
/// - Send方法带返回值返回值
/// - Send方法带返回值处理null命令
/// </summary>
[TestFixture] [TestFixture]
public class CommandBusTests public class CommandBusTests
{ {
@ -15,6 +23,9 @@ public class CommandBusTests
private CommandBus _commandBus = null!; private CommandBus _commandBus = null!;
/// <summary>
/// 测试Send方法执行命令
/// </summary>
[Test] [Test]
public void Send_Should_Execute_Command() public void Send_Should_Execute_Command()
{ {
@ -26,12 +37,18 @@ public class CommandBusTests
Assert.That(command.ExecutedValue, Is.EqualTo(42)); Assert.That(command.ExecutedValue, Is.EqualTo(42));
} }
/// <summary>
/// 测试Send方法处理null命令时抛出ArgumentNullException异常
/// </summary>
[Test] [Test]
public void Send_WithNullCommand_Should_ThrowArgumentNullException() public void Send_WithNullCommand_Should_ThrowArgumentNullException()
{ {
Assert.Throws<ArgumentNullException>(() => _commandBus.Send(null!)); Assert.Throws<ArgumentNullException>(() => _commandBus.Send(null!));
} }
/// <summary>
/// 测试Send方法带返回值正确返回值
/// </summary>
[Test] [Test]
public void Send_WithResult_Should_Return_Value() public void Send_WithResult_Should_Return_Value()
{ {
@ -44,6 +61,9 @@ public class CommandBusTests
Assert.That(result, Is.EqualTo(200)); Assert.That(result, Is.EqualTo(200));
} }
/// <summary>
/// 测试Send方法带返回值处理null命令时抛出ArgumentNullException异常
/// </summary>
[Test] [Test]
public void Send_WithResult_AndNullCommand_Should_ThrowArgumentNullException() public void Send_WithResult_AndNullCommand_Should_ThrowArgumentNullException()
{ {
@ -51,20 +71,44 @@ public class CommandBusTests
} }
} }
/// <summary>
/// 测试用命令输入类实现ICommandInput接口
/// </summary>
public sealed class TestCommandInput : ICommandInput public sealed class TestCommandInput : ICommandInput
{ {
/// <summary>
/// 获取或设置值
/// </summary>
public int Value { get; init; } public int Value { get; init; }
} }
/// <summary>
/// 测试用命令类继承AbstractCommand
/// </summary>
public sealed class TestCommand : AbstractCommand<TestCommandInput> public sealed class TestCommand : AbstractCommand<TestCommandInput>
{ {
/// <summary>
/// 构造函数
/// </summary>
/// <param name="input">命令输入</param>
public TestCommand(TestCommandInput input) : base(input) public TestCommand(TestCommandInput input) : base(input)
{ {
} }
/// <summary>
/// 获取命令是否已执行
/// </summary>
public bool Executed { get; private set; } public bool Executed { get; private set; }
/// <summary>
/// 获取执行的值
/// </summary>
public int ExecutedValue { get; private set; } public int ExecutedValue { get; private set; }
/// <summary>
/// 执行命令的重写方法
/// </summary>
/// <param name="input">命令输入</param>
protected override void OnExecute(TestCommandInput input) protected override void OnExecute(TestCommandInput input)
{ {
Executed = true; Executed = true;
@ -72,14 +116,29 @@ public sealed class TestCommand : AbstractCommand<TestCommandInput>
} }
} }
/// <summary>
/// 测试用带返回值的命令类继承AbstractCommand
/// </summary>
public sealed class TestCommandWithResult : AbstractCommand<TestCommandInput, int> public sealed class TestCommandWithResult : AbstractCommand<TestCommandInput, int>
{ {
/// <summary>
/// 构造函数
/// </summary>
/// <param name="input">命令输入</param>
public TestCommandWithResult(TestCommandInput input) : base(input) public TestCommandWithResult(TestCommandInput input) : base(input)
{ {
} }
/// <summary>
/// 获取命令是否已执行
/// </summary>
public bool Executed { get; private set; } public bool Executed { get; private set; }
/// <summary>
/// 执行命令并返回结果的重写方法
/// </summary>
/// <param name="input">命令输入</param>
/// <returns>执行结果</returns>
protected override int OnExecute(TestCommandInput input) protected override int OnExecute(TestCommandInput input)
{ {
Executed = true; Executed = true;

View File

@ -4,9 +4,15 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.environment; namespace GFramework.Core.Tests.environment;
/// <summary>
/// 测试环境相关的单元测试类,用于验证环境管理功能的正确性
/// </summary>
[TestFixture] [TestFixture]
public class EnvironmentTests public class EnvironmentTests
{ {
/// <summary>
/// 在每个测试方法执行前进行初始化设置
/// </summary>
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -16,6 +22,9 @@ public class EnvironmentTests
private TestEnvironment _environment = null!; private TestEnvironment _environment = null!;
/// <summary>
/// 验证默认环境的名称是否正确返回"Default"
/// </summary>
[Test] [Test]
public void DefaultEnvironment_Name_Should_ReturnDefault() public void DefaultEnvironment_Name_Should_ReturnDefault()
{ {
@ -24,6 +33,9 @@ public class EnvironmentTests
Assert.That(env.Name, Is.EqualTo("Default")); Assert.That(env.Name, Is.EqualTo("Default"));
} }
/// <summary>
/// 验证默认环境的初始化方法不会抛出异常
/// </summary>
[Test] [Test]
public void DefaultEnvironment_Initialize_Should_NotThrow() public void DefaultEnvironment_Initialize_Should_NotThrow()
{ {
@ -32,6 +44,9 @@ public class EnvironmentTests
Assert.DoesNotThrow(() => env.Initialize()); Assert.DoesNotThrow(() => env.Initialize());
} }
/// <summary>
/// 验证当键存在时Get方法应该返回正确的值
/// </summary>
[Test] [Test]
public void Get_Should_Return_Value_When_Key_Exists() public void Get_Should_Return_Value_When_Key_Exists()
{ {
@ -42,6 +57,9 @@ public class EnvironmentTests
Assert.That(result, Is.EqualTo("testValue")); Assert.That(result, Is.EqualTo("testValue"));
} }
/// <summary>
/// 验证当键不存在时Get方法应该返回null
/// </summary>
[Test] [Test]
public void Get_Should_ReturnNull_When_Key_Not_Exists() public void Get_Should_ReturnNull_When_Key_Not_Exists()
{ {
@ -50,6 +68,9 @@ public class EnvironmentTests
Assert.That(result, Is.Null); Assert.That(result, Is.Null);
} }
/// <summary>
/// 验证当类型不匹配时Get方法应该返回null
/// </summary>
[Test] [Test]
public void Get_Should_ReturnNull_When_Type_Does_Not_Match() public void Get_Should_ReturnNull_When_Type_Does_Not_Match()
{ {
@ -60,6 +81,9 @@ public class EnvironmentTests
Assert.That(result, Is.Null); Assert.That(result, Is.Null);
} }
/// <summary>
/// 验证当键存在时TryGet方法应该返回true并输出正确的值
/// </summary>
[Test] [Test]
public void TryGet_Should_ReturnTrue_And_Value_When_Key_Exists() public void TryGet_Should_ReturnTrue_And_Value_When_Key_Exists()
{ {
@ -71,6 +95,9 @@ public class EnvironmentTests
Assert.That(value, Is.EqualTo("testValue")); Assert.That(value, Is.EqualTo("testValue"));
} }
/// <summary>
/// 验证当键不存在时TryGet方法应该返回false且输出值为null
/// </summary>
[Test] [Test]
public void TryGet_Should_ReturnFalse_When_Key_Not_Exists() public void TryGet_Should_ReturnFalse_When_Key_Not_Exists()
{ {
@ -80,6 +107,9 @@ public class EnvironmentTests
Assert.That(value, Is.Null); Assert.That(value, Is.Null);
} }
/// <summary>
/// 验证当类型不匹配时TryGet方法应该返回false且输出值为null
/// </summary>
[Test] [Test]
public void TryGet_Should_ReturnFalse_When_Type_Does_Not_Match() public void TryGet_Should_ReturnFalse_When_Type_Does_Not_Match()
{ {
@ -91,6 +121,9 @@ public class EnvironmentTests
Assert.That(value, Is.Null); Assert.That(value, Is.Null);
} }
/// <summary>
/// 验证当键存在时GetRequired方法应该返回正确的值
/// </summary>
[Test] [Test]
public void GetRequired_Should_Return_Value_When_Key_Exists() public void GetRequired_Should_Return_Value_When_Key_Exists()
{ {
@ -101,6 +134,9 @@ public class EnvironmentTests
Assert.That(result, Is.EqualTo("testValue")); Assert.That(result, Is.EqualTo("testValue"));
} }
/// <summary>
/// 验证当键不存在时GetRequired方法应该抛出InvalidOperationException异常
/// </summary>
[Test] [Test]
public void GetRequired_Should_ThrowInvalidOperationException_When_Key_Not_Exists() public void GetRequired_Should_ThrowInvalidOperationException_When_Key_Not_Exists()
{ {
@ -108,6 +144,9 @@ public class EnvironmentTests
_environment.GetRequired<string>("nonExistentKey")); _environment.GetRequired<string>("nonExistentKey"));
} }
/// <summary>
/// 验证Register方法应该将值添加到字典中
/// </summary>
[Test] [Test]
public void Register_Should_Add_Value_To_Dictionary() public void Register_Should_Add_Value_To_Dictionary()
{ {
@ -118,6 +157,9 @@ public class EnvironmentTests
Assert.That(result, Is.EqualTo("newValue")); Assert.That(result, Is.EqualTo("newValue"));
} }
/// <summary>
/// 验证Register方法应该覆盖已存在的值
/// </summary>
[Test] [Test]
public void Register_Should_Overwrite_Existing_Value() public void Register_Should_Overwrite_Existing_Value()
{ {
@ -129,6 +171,9 @@ public class EnvironmentTests
Assert.That(result, Is.EqualTo("value2")); Assert.That(result, Is.EqualTo("value2"));
} }
/// <summary>
/// 验证通过IEnvironment接口的Register方法应该能够添加值
/// </summary>
[Test] [Test]
public void IEnvironment_Register_Should_Add_Value() public void IEnvironment_Register_Should_Add_Value()
{ {
@ -141,15 +186,29 @@ public class EnvironmentTests
} }
} }
/// <summary>
/// 测试环境实现类继承自EnvironmentBase
/// </summary>
public class TestEnvironment : EnvironmentBase public class TestEnvironment : EnvironmentBase
{ {
/// <summary>
/// 获取环境名称
/// </summary>
public override string Name { get; } = "TestEnvironment"; public override string Name { get; } = "TestEnvironment";
/// <summary>
/// 注册键值对到环境中
/// </summary>
/// <param name="key">要注册的键</param>
/// <param name="value">要注册的值</param>
public new void Register(string key, object value) public new void Register(string key, object value)
{ {
base.Register(key, value); base.Register(key, value);
} }
/// <summary>
/// 初始化环境
/// </summary>
public override void Initialize() public override void Initialize()
{ {
} }

View File

@ -1,20 +1,33 @@
using System;
using GFramework.Core.events; using GFramework.Core.events;
using NUnit.Framework; using NUnit.Framework;
namespace GFramework.Core.Tests.events; namespace GFramework.Core.Tests.events;
/// <summary>
/// ArchitectureEvents类的单元测试
/// 测试内容包括:
/// - ArchitectureLifecycleReadyEvent事件触发
/// - ArchitectureDestroyingEvent事件触发
/// - ArchitectureDestroyedEvent事件触发
/// - ArchitectureFailedInitializationEvent事件触发
/// - 事件的参数传递
/// - 事件的订阅和取消订阅
/// - 事件顺序验证LifecycleReady -> Destroying -> Destroyed
/// </summary>
[TestFixture] [TestFixture]
public class ArchitectureEventsTests public class ArchitectureEventsTests
{ {
private EventBus? _eventBus;
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
_eventBus = new EventBus(); _eventBus = new EventBus();
} }
private EventBus? _eventBus;
/// <summary>
/// 测试ArchitectureLifecycleReadyEvent事件可以创建并发送
/// </summary>
[Test] [Test]
public void ArchitectureLifecycleReadyEvent_Should_Be_Created_And_Sent() public void ArchitectureLifecycleReadyEvent_Should_Be_Created_And_Sent()
{ {
@ -26,6 +39,9 @@ public class ArchitectureEventsTests
Assert.That(eventReceived, Is.True); Assert.That(eventReceived, Is.True);
} }
/// <summary>
/// 测试ArchitectureDestroyingEvent事件可以创建并发送
/// </summary>
[Test] [Test]
public void ArchitectureDestroyingEvent_Should_Be_Created_And_Sent() public void ArchitectureDestroyingEvent_Should_Be_Created_And_Sent()
{ {
@ -37,6 +53,9 @@ public class ArchitectureEventsTests
Assert.That(eventReceived, Is.True); Assert.That(eventReceived, Is.True);
} }
/// <summary>
/// 测试ArchitectureDestroyedEvent事件可以创建并发送
/// </summary>
[Test] [Test]
public void ArchitectureDestroyedEvent_Should_Be_Created_And_Sent() public void ArchitectureDestroyedEvent_Should_Be_Created_And_Sent()
{ {
@ -48,6 +67,9 @@ public class ArchitectureEventsTests
Assert.That(eventReceived, Is.True); Assert.That(eventReceived, Is.True);
} }
/// <summary>
/// 测试ArchitectureFailedInitializationEvent事件可以创建并发送
/// </summary>
[Test] [Test]
public void ArchitectureFailedInitializationEvent_Should_Be_Created_And_Sent() public void ArchitectureFailedInitializationEvent_Should_Be_Created_And_Sent()
{ {
@ -59,6 +81,9 @@ public class ArchitectureEventsTests
Assert.That(eventReceived, Is.True); Assert.That(eventReceived, Is.True);
} }
/// <summary>
/// 测试事件按正确顺序发送
/// </summary>
[Test] [Test]
public void Events_Should_Be_Sent_In_Correct_Order() public void Events_Should_Be_Sent_In_Correct_Order()
{ {
@ -78,6 +103,9 @@ public class ArchitectureEventsTests
Assert.That(events[2], Is.EqualTo("Destroyed")); Assert.That(events[2], Is.EqualTo("Destroyed"));
} }
/// <summary>
/// 测试多个订阅者都能接收到事件
/// </summary>
[Test] [Test]
public void Multiple_Subscribers_Should_All_Receive_Events() public void Multiple_Subscribers_Should_All_Receive_Events()
{ {
@ -93,6 +121,9 @@ public class ArchitectureEventsTests
Assert.That(count2, Is.EqualTo(1)); Assert.That(count2, Is.EqualTo(1));
} }
/// <summary>
/// 测试事件取消订阅后不再接收未来事件
/// </summary>
[Test] [Test]
public void Event_UnRegister_Should_Prevent_Future_Events() public void Event_UnRegister_Should_Prevent_Future_Events()
{ {
@ -108,6 +139,9 @@ public class ArchitectureEventsTests
Assert.That(count, Is.EqualTo(1)); Assert.That(count, Is.EqualTo(1));
} }
/// <summary>
/// 测试不同类型事件互不干扰
/// </summary>
[Test] [Test]
public void Different_Events_Should_Not_Interfere() public void Different_Events_Should_Not_Interfere()
{ {
@ -127,6 +161,9 @@ public class ArchitectureEventsTests
Assert.That(destroyingReceived, Is.True); Assert.That(destroyingReceived, Is.True);
} }
/// <summary>
/// 测试事件可以在没有订阅者时发送
/// </summary>
[Test] [Test]
public void Event_Can_Be_Sent_Without_Subscribers() public void Event_Can_Be_Sent_Without_Subscribers()
{ {
@ -134,4 +171,3 @@ public class ArchitectureEventsTests
Throws.Nothing); Throws.Nothing);
} }
} }

View File

@ -3,9 +3,15 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.events; namespace GFramework.Core.Tests.events;
/// <summary>
/// EasyEvents功能测试类用于验证事件系统的注册、触发和参数传递功能
/// </summary>
[TestFixture] [TestFixture]
public class EasyEventsTests public class EasyEventsTests
{ {
/// <summary>
/// 测试用例初始化方法在每个测试方法执行前设置EasyEvents实例
/// </summary>
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -14,6 +20,9 @@ public class EasyEventsTests
private EasyEvents _easyEvents = null!; private EasyEvents _easyEvents = null!;
/// <summary>
/// 测试单参数事件的功能验证事件能够正确接收并传递int类型参数
/// </summary>
[Test] [Test]
public void Get_EventT_Should_Trigger_With_Parameter() public void Get_EventT_Should_Trigger_With_Parameter()
{ {
@ -21,11 +30,16 @@ public class EasyEventsTests
var @event = EasyEvents.GetOrAdd<Event<int>>(); var @event = EasyEvents.GetOrAdd<Event<int>>();
@event.Register(value => { receivedValue = value; }); @event.Register(value => { receivedValue = value; });
// 触发事件并传递参数42
@event.Trigger(42); @event.Trigger(42);
Assert.That(receivedValue, Is.EqualTo(42)); Assert.That(receivedValue, Is.EqualTo(42));
} }
/// <summary>
/// 测试双参数事件的功能验证事件能够正确接收并传递int和string类型的参数
/// </summary>
[Test] [Test]
public void Get_EventTTK_Should_Trigger_With_Two_Parameters() public void Get_EventTTK_Should_Trigger_With_Two_Parameters()
{ {
@ -38,6 +52,8 @@ public class EasyEventsTests
receivedInt = i; receivedInt = i;
receivedString = s; receivedString = s;
}); });
// 触发事件并传递两个参数整数100和字符串"hello"
@event.Trigger(100, "hello"); @event.Trigger(100, "hello");
Assert.That(receivedInt, Is.EqualTo(100)); Assert.That(receivedInt, Is.EqualTo(100));

View File

@ -3,9 +3,15 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.events; namespace GFramework.Core.Tests.events;
/// <summary>
/// EventBus测试类用于验证事件总线的各种功能
/// </summary>
[TestFixture] [TestFixture]
public class EventBusTests public class EventBusTests
{ {
/// <summary>
/// 测试设置方法在每个测试方法执行前初始化EventBus实例
/// </summary>
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -14,6 +20,10 @@ public class EventBusTests
private EventBus _eventBus = null!; private EventBus _eventBus = null!;
/// <summary>
/// 测试注册事件处理器的功能
/// 验证注册的处理器能够在发送对应事件时被正确调用
/// </summary>
[Test] [Test]
public void Register_Should_Add_Handler() public void Register_Should_Add_Handler()
{ {
@ -25,6 +35,10 @@ public class EventBusTests
Assert.That(called, Is.True); Assert.That(called, Is.True);
} }
/// <summary>
/// 测试注销事件处理器的功能
/// 验证已注册的处理器在注销后不会再被调用
/// </summary>
[Test] [Test]
public void UnRegister_Should_Remove_Handler() public void UnRegister_Should_Remove_Handler()
{ {
@ -33,13 +47,19 @@ public class EventBusTests
Action<EventBusTestsEvent> handler = @event => { count++; }; Action<EventBusTestsEvent> handler = @event => { count++; };
_eventBus.Register(handler); _eventBus.Register(handler);
_eventBus.Send<EventBusTestsEvent>(); _eventBus.Send<EventBusTestsEvent>();
// 验证处理器被调用一次
Assert.That(count, Is.EqualTo(1)); Assert.That(count, Is.EqualTo(1));
_eventBus.UnRegister(handler); _eventBus.UnRegister(handler);
_eventBus.Send<EventBusTestsEvent>(); _eventBus.Send<EventBusTestsEvent>();
// 验证处理器在注销后不再被调用
Assert.That(count, Is.EqualTo(1)); Assert.That(count, Is.EqualTo(1));
} }
/// <summary>
/// 测试发送事件时调用所有处理器的功能
/// 验证同一事件类型的多个处理器都能被正确调用
/// </summary>
[Test] [Test]
public void SendEvent_Should_Invoke_All_Handlers() public void SendEvent_Should_Invoke_All_Handlers()
{ {
@ -51,11 +71,15 @@ public class EventBusTests
_eventBus.Send<EventBusTestsEvent>(); _eventBus.Send<EventBusTestsEvent>();
// 验证所有处理器都被调用一次
Assert.That(count1, Is.EqualTo(1)); Assert.That(count1, Is.EqualTo(1));
Assert.That(count2, Is.EqualTo(1)); Assert.That(count2, Is.EqualTo(1));
} }
} }
/// <summary>
/// EventBus测试专用事件类
/// </summary>
public class EventBusTestsEvent public class EventBusTestsEvent
{ {
} }

View File

@ -3,9 +3,15 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.events; namespace GFramework.Core.Tests.events;
/// <summary>
/// 测试事件系统功能的测试类
/// </summary>
[TestFixture] [TestFixture]
public class EventTests public class EventTests
{ {
/// <summary>
/// 在每个测试方法执行前进行初始化设置
/// </summary>
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -18,6 +24,9 @@ public class EventTests
private Event<int> _eventInt = null!; private Event<int> _eventInt = null!;
private Event<int, string> _eventIntString = null!; private Event<int, string> _eventIntString = null!;
/// <summary>
/// 测试EasyEvent注册功能是否正确添加处理器
/// </summary>
[Test] [Test]
public void EasyEvent_Register_Should_Add_Handler() public void EasyEvent_Register_Should_Add_Handler()
{ {
@ -29,6 +38,9 @@ public class EventTests
Assert.That(called, Is.True); Assert.That(called, Is.True);
} }
/// <summary>
/// 测试EasyEvent取消注册功能是否正确移除处理器
/// </summary>
[Test] [Test]
public void EasyEvent_UnRegister_Should_Remove_Handler() public void EasyEvent_UnRegister_Should_Remove_Handler()
{ {
@ -44,6 +56,9 @@ public class EventTests
Assert.That(count, Is.EqualTo(1)); Assert.That(count, Is.EqualTo(1));
} }
/// <summary>
/// 测试EasyEvent多个处理器是否都能被调用
/// </summary>
[Test] [Test]
public void EasyEvent_Multiple_Handlers_Should_All_Be_Called() public void EasyEvent_Multiple_Handlers_Should_All_Be_Called()
{ {
@ -59,6 +74,9 @@ public class EventTests
Assert.That(count2, Is.EqualTo(1)); Assert.That(count2, Is.EqualTo(1));
} }
/// <summary>
/// 测试带泛型参数的事件注册功能是否正确添加处理器
/// </summary>
[Test] [Test]
public void EventT_Register_Should_Add_Handler() public void EventT_Register_Should_Add_Handler()
{ {
@ -70,6 +88,9 @@ public class EventTests
Assert.That(receivedValue, Is.EqualTo(42)); Assert.That(receivedValue, Is.EqualTo(42));
} }
/// <summary>
/// 测试带泛型参数的事件取消注册功能是否正确移除处理器
/// </summary>
[Test] [Test]
public void EventT_UnRegister_Should_Remove_Handler() public void EventT_UnRegister_Should_Remove_Handler()
{ {
@ -85,6 +106,9 @@ public class EventTests
Assert.That(count, Is.EqualTo(1)); Assert.That(count, Is.EqualTo(1));
} }
/// <summary>
/// 测试带泛型参数的事件多个处理器是否都能被调用
/// </summary>
[Test] [Test]
public void EventT_Multiple_Handlers_Should_All_Be_Called() public void EventT_Multiple_Handlers_Should_All_Be_Called()
{ {
@ -100,6 +124,9 @@ public class EventTests
Assert.That(values, Does.Contain(10)); Assert.That(values, Does.Contain(10));
} }
/// <summary>
/// 测试带两个泛型参数的事件注册功能是否正确添加处理器
/// </summary>
[Test] [Test]
public void EventTTK_Register_Should_Add_Handler() public void EventTTK_Register_Should_Add_Handler()
{ {
@ -117,6 +144,9 @@ public class EventTests
Assert.That(receivedString, Is.EqualTo("test")); Assert.That(receivedString, Is.EqualTo("test"));
} }
/// <summary>
/// 测试带两个泛型参数的事件取消注册功能是否正确移除处理器
/// </summary>
[Test] [Test]
public void EventTTK_UnRegister_Should_Remove_Handler() public void EventTTK_UnRegister_Should_Remove_Handler()
{ {

View File

@ -3,9 +3,16 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.events; namespace GFramework.Core.Tests.events;
/// <summary>
/// 测试OrEvent类的功能验证其在多个事件中的逻辑或操作行为
/// </summary>
[TestFixture] [TestFixture]
public class OrEventTests public class OrEventTests
{ {
/// <summary>
/// 测试当任意一个事件触发时OrEvent应该被触发
/// 验证基本的OR逻辑功能
/// </summary>
[Test] [Test]
public void OrEvent_Should_Trigger_When_Any_Event_Fires() public void OrEvent_Should_Trigger_When_Any_Event_Fires()
{ {
@ -16,6 +23,7 @@ public class OrEventTests
var triggered = false; var triggered = false;
orEvent.Register(() => { triggered = true; }); orEvent.Register(() => { triggered = true; });
// 将两个事件添加到OrEvent中
orEvent.Or(event1).Or(event2); orEvent.Or(event1).Or(event2);
event1.Trigger(0); event1.Trigger(0);
@ -23,6 +31,10 @@ public class OrEventTests
Assert.That(triggered, Is.True); Assert.That(triggered, Is.True);
} }
/// <summary>
/// 测试当第二个事件触发时OrEvent应该被触发
/// 验证OR逻辑对所有注册事件都有效
/// </summary>
[Test] [Test]
public void OrEvent_Should_Trigger_When_Second_Event_Fires() public void OrEvent_Should_Trigger_When_Second_Event_Fires()
{ {
@ -33,6 +45,7 @@ public class OrEventTests
var triggered = false; var triggered = false;
orEvent.Register(() => { triggered = true; }); orEvent.Register(() => { triggered = true; });
// 将两个事件添加到OrEvent中
orEvent.Or(event1).Or(event2); orEvent.Or(event1).Or(event2);
event2.Trigger(0); event2.Trigger(0);
@ -40,6 +53,10 @@ public class OrEventTests
Assert.That(triggered, Is.True); Assert.That(triggered, Is.True);
} }
/// <summary>
/// 测试OrEvent支持多个处理程序
/// 验证单个OrEvent可以注册多个回调函数
/// </summary>
[Test] [Test]
public void OrEvent_Should_Support_Multiple_Handlers() public void OrEvent_Should_Support_Multiple_Handlers()
{ {
@ -52,6 +69,7 @@ public class OrEventTests
orEvent.Register(() => { count1++; }); orEvent.Register(() => { count1++; });
orEvent.Register(() => { count2++; }); orEvent.Register(() => { count2++; });
// 将事件添加到OrEvent中
orEvent.Or(@event); orEvent.Or(@event);
@event.Trigger(0); @event.Trigger(0);
@ -59,6 +77,10 @@ public class OrEventTests
Assert.That(count2, Is.EqualTo(1)); Assert.That(count2, Is.EqualTo(1));
} }
/// <summary>
/// 测试UnRegister方法应该移除处理程序
/// 验证注销功能能够正确移除已注册的回调函数
/// </summary>
[Test] [Test]
public void OrEvent_UnRegister_Should_Remove_Handler() public void OrEvent_UnRegister_Should_Remove_Handler()
{ {
@ -74,6 +96,7 @@ public class OrEventTests
@event.Trigger(0); @event.Trigger(0);
Assert.That(count, Is.EqualTo(1)); Assert.That(count, Is.EqualTo(1));
// 注销处理程序
orEvent.UnRegister(handler); orEvent.UnRegister(handler);
@event.Trigger(0); @event.Trigger(0);
Assert.That(count, Is.EqualTo(1)); Assert.That(count, Is.EqualTo(1));

View File

@ -4,9 +4,15 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.events; namespace GFramework.Core.Tests.events;
/// <summary>
/// 注销功能测试类,用于测试不同类型的注销行为
/// </summary>
[TestFixture] [TestFixture]
public class UnRegisterTests public class UnRegisterTests
{ {
/// <summary>
/// 测试DefaultUnRegister在调用注销时是否正确触发回调函数
/// </summary>
[Test] [Test]
public void DefaultUnRegister_Should_InvokeCallback_When_UnRegisterCalled() public void DefaultUnRegister_Should_InvokeCallback_When_UnRegisterCalled()
{ {
@ -18,6 +24,9 @@ public class UnRegisterTests
Assert.That(invoked, Is.True); Assert.That(invoked, Is.True);
} }
/// <summary>
/// 测试DefaultUnRegister在注销后是否清除回调函数防止重复执行
/// </summary>
[Test] [Test]
public void DefaultUnRegister_Should_ClearCallback_After_UnRegister() public void DefaultUnRegister_Should_ClearCallback_After_UnRegister()
{ {
@ -30,6 +39,9 @@ public class UnRegisterTests
Assert.That(callCount, Is.EqualTo(1)); Assert.That(callCount, Is.EqualTo(1));
} }
/// <summary>
/// 测试DefaultUnRegister在传入空回调函数时不会抛出异常
/// </summary>
[Test] [Test]
public void DefaultUnRegister_WithNullCallback_Should_NotThrow() public void DefaultUnRegister_WithNullCallback_Should_NotThrow()
{ {
@ -38,6 +50,9 @@ public class UnRegisterTests
Assert.DoesNotThrow(() => unRegister.UnRegister()); Assert.DoesNotThrow(() => unRegister.UnRegister());
} }
/// <summary>
/// 测试BindablePropertyUnRegister是否能正确从属性中注销事件处理器
/// </summary>
[Test] [Test]
public void BindablePropertyUnRegister_Should_UnRegister_From_Property() public void BindablePropertyUnRegister_Should_UnRegister_From_Property()
{ {
@ -55,6 +70,9 @@ public class UnRegisterTests
Assert.That(callCount, Is.EqualTo(0)); Assert.That(callCount, Is.EqualTo(0));
} }
/// <summary>
/// 测试BindablePropertyUnRegister在注销后是否清除内部引用
/// </summary>
[Test] [Test]
public void BindablePropertyUnRegister_Should_Clear_References() public void BindablePropertyUnRegister_Should_Clear_References()
{ {
@ -65,10 +83,14 @@ public class UnRegisterTests
unRegister.UnRegister(); unRegister.UnRegister();
// 验证注销后引用被清除
Assert.That(unRegister.BindableProperty, Is.Null); Assert.That(unRegister.BindableProperty, Is.Null);
Assert.That(unRegister.OnValueChanged, Is.Null); Assert.That(unRegister.OnValueChanged, Is.Null);
} }
/// <summary>
/// 测试BindablePropertyUnRegister在传入空属性时不会抛出异常
/// </summary>
[Test] [Test]
public void BindablePropertyUnRegister_WithNull_Property_Should_NotThrow() public void BindablePropertyUnRegister_WithNull_Property_Should_NotThrow()
{ {
@ -78,6 +100,9 @@ public class UnRegisterTests
Assert.DoesNotThrow(() => unRegister.UnRegister()); Assert.DoesNotThrow(() => unRegister.UnRegister());
} }
/// <summary>
/// 测试BindablePropertyUnRegister在传入空处理器时不会抛出异常
/// </summary>
[Test] [Test]
public void BindablePropertyUnRegister_WithNull_Handler_Should_NotThrow() public void BindablePropertyUnRegister_WithNull_Handler_Should_NotThrow()
{ {

View File

@ -3,9 +3,15 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.extensions; namespace GFramework.Core.Tests.extensions;
/// <summary>
/// 测试ObjectExtensions扩展方法的功能
/// </summary>
[TestFixture] [TestFixture]
public class ObjectExtensionsTests public class ObjectExtensionsTests
{ {
/// <summary>
/// 验证IfType方法在类型匹配时执行指定操作
/// </summary>
[Test] [Test]
public void IfType_Should_Execute_Action_When_Type_Matches() public void IfType_Should_Execute_Action_When_Type_Matches()
{ {
@ -17,6 +23,9 @@ public class ObjectExtensionsTests
Assert.That(executed, Is.True); Assert.That(executed, Is.True);
} }
/// <summary>
/// 验证IfType方法在类型不匹配时不执行指定操作
/// </summary>
[Test] [Test]
public void IfType_Should_Not_Execute_Action_When_Type_Does_Not_Match() public void IfType_Should_Not_Execute_Action_When_Type_Does_Not_Match()
{ {
@ -28,6 +37,9 @@ public class ObjectExtensionsTests
Assert.That(executed, Is.False); Assert.That(executed, Is.False);
} }
/// <summary>
/// 验证IfType方法在类型匹配且谓词条件为真时执行指定操作
/// </summary>
[Test] [Test]
public void IfType_WithPredicate_Should_Execute_When_Type_Matches_And_Predicate_True() public void IfType_WithPredicate_Should_Execute_When_Type_Matches_And_Predicate_True()
{ {
@ -39,6 +51,9 @@ public class ObjectExtensionsTests
Assert.That(executed, Is.True); Assert.That(executed, Is.True);
} }
/// <summary>
/// 验证IfType方法在谓词条件为假时不执行指定操作
/// </summary>
[Test] [Test]
public void IfType_WithPredicate_Should_Not_Execute_When_Predicate_False() public void IfType_WithPredicate_Should_Not_Execute_When_Predicate_False()
{ {
@ -50,6 +65,9 @@ public class ObjectExtensionsTests
Assert.That(executed, Is.False); Assert.That(executed, Is.False);
} }
/// <summary>
/// 验证IfType方法在类型匹配时执行匹配操作在类型不匹配时执行不匹配操作
/// </summary>
[Test] [Test]
public void IfType_WithBoth_Actions_Should_Execute_Correct_Action() public void IfType_WithBoth_Actions_Should_Execute_Correct_Action()
{ {
@ -66,6 +84,9 @@ public class ObjectExtensionsTests
Assert.That(noMatchCount, Is.EqualTo(0)); Assert.That(noMatchCount, Is.EqualTo(0));
} }
/// <summary>
/// 验证IfType方法在类型匹配时返回转换结果
/// </summary>
[Test] [Test]
public void IfType_WithResult_Should_Return_Value_When_Type_Matches() public void IfType_WithResult_Should_Return_Value_When_Type_Matches()
{ {
@ -76,6 +97,9 @@ public class ObjectExtensionsTests
Assert.That(result, Is.EqualTo("Test")); Assert.That(result, Is.EqualTo("Test"));
} }
/// <summary>
/// 验证IfType方法在类型不匹配时返回默认值
/// </summary>
[Test] [Test]
public void IfType_WithResult_Should_Return_Default_When_Type_Does_Not_Match() public void IfType_WithResult_Should_Return_Default_When_Type_Does_Not_Match()
{ {
@ -86,6 +110,9 @@ public class ObjectExtensionsTests
Assert.That(result, Is.Null); Assert.That(result, Is.Null);
} }
/// <summary>
/// 验证As方法在类型匹配时返回实例
/// </summary>
[Test] [Test]
public void As_Should_Return_Instance_When_Type_Matches() public void As_Should_Return_Instance_When_Type_Matches()
{ {
@ -97,6 +124,9 @@ public class ObjectExtensionsTests
Assert.That(result, Is.SameAs(obj)); Assert.That(result, Is.SameAs(obj));
} }
/// <summary>
/// 验证As方法在类型不匹配时返回null
/// </summary>
[Test] [Test]
public void As_Should_Return_Null_When_Type_Does_Not_Match() public void As_Should_Return_Null_When_Type_Does_Not_Match()
{ {
@ -107,6 +137,9 @@ public class ObjectExtensionsTests
Assert.That(result, Is.Null); Assert.That(result, Is.Null);
} }
/// <summary>
/// 验证Do方法执行操作并返回对象本身
/// </summary>
[Test] [Test]
public void Do_Should_Execute_Action_And_Return_Object() public void Do_Should_Execute_Action_And_Return_Object()
{ {
@ -118,6 +151,9 @@ public class ObjectExtensionsTests
Assert.That(obj.Value, Is.EqualTo(10)); Assert.That(obj.Value, Is.EqualTo(10));
} }
/// <summary>
/// 验证Do方法支持链式调用
/// </summary>
[Test] [Test]
public void Do_Should_Support_Chaining() public void Do_Should_Support_Chaining()
{ {
@ -130,6 +166,9 @@ public class ObjectExtensionsTests
Assert.That(obj.Name, Is.EqualTo("B")); Assert.That(obj.Name, Is.EqualTo("B"));
} }
/// <summary>
/// 验证SwitchType方法执行匹配的处理器
/// </summary>
[Test] [Test]
public void SwitchType_Should_Execute_Matching_Handler() public void SwitchType_Should_Execute_Matching_Handler()
{ {
@ -144,6 +183,9 @@ public class ObjectExtensionsTests
Assert.That(executed, Is.True); Assert.That(executed, Is.True);
} }
/// <summary>
/// 验证SwitchType方法只执行第一个匹配的处理器
/// </summary>
[Test] [Test]
public void SwitchType_Should_Execute_First_Matching_Handler() public void SwitchType_Should_Execute_First_Matching_Handler()
{ {
@ -158,6 +200,9 @@ public class ObjectExtensionsTests
Assert.That(count, Is.EqualTo(1)); Assert.That(count, Is.EqualTo(1));
} }
/// <summary>
/// 验证SwitchType方法在没有匹配项时不执行任何处理器
/// </summary>
[Test] [Test]
public void SwitchType_Should_Not_Execute_When_No_Match() public void SwitchType_Should_Not_Execute_When_No_Match()
{ {
@ -173,8 +218,18 @@ public class ObjectExtensionsTests
} }
} }
/// <summary>
/// 测试用的简单类
/// </summary>
public class TestClass public class TestClass
{ {
/// <summary>
/// 获取或设置整数值
/// </summary>
public int Value { get; set; } public int Value { get; set; }
/// <summary>
/// 获取或设置名称字符串
/// </summary>
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
} }

View File

@ -5,9 +5,15 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.extensions; namespace GFramework.Core.Tests.extensions;
/// <summary>
/// 测试UnRegisterList扩展方法的功能
/// </summary>
[TestFixture] [TestFixture]
public class UnRegisterListExtensionTests public class UnRegisterListExtensionTests
{ {
/// <summary>
/// 在每个测试方法执行前初始化测试环境
/// </summary>
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -16,6 +22,9 @@ public class UnRegisterListExtensionTests
private TestUnRegisterList _unRegisterList = null!; private TestUnRegisterList _unRegisterList = null!;
/// <summary>
/// 验证AddToUnregisterList方法能够正确将元素添加到列表中
/// </summary>
[Test] [Test]
public void AddToUnregisterList_Should_Add_To_List() public void AddToUnregisterList_Should_Add_To_List()
{ {
@ -26,6 +35,9 @@ public class UnRegisterListExtensionTests
Assert.That(_unRegisterList.UnregisterList.Count, Is.EqualTo(1)); Assert.That(_unRegisterList.UnregisterList.Count, Is.EqualTo(1));
} }
/// <summary>
/// 验证AddToUnregisterList方法能够正确添加多个元素到列表中
/// </summary>
[Test] [Test]
public void AddToUnregisterList_Should_Add_Multiple_Elements() public void AddToUnregisterList_Should_Add_Multiple_Elements()
{ {
@ -40,6 +52,9 @@ public class UnRegisterListExtensionTests
Assert.That(_unRegisterList.UnregisterList.Count, Is.EqualTo(3)); Assert.That(_unRegisterList.UnregisterList.Count, Is.EqualTo(3));
} }
/// <summary>
/// 验证UnRegisterAll方法能够正确注销所有元素
/// </summary>
[Test] [Test]
public void UnRegisterAll_Should_UnRegister_All_Elements() public void UnRegisterAll_Should_UnRegister_All_Elements()
{ {
@ -55,6 +70,7 @@ public class UnRegisterListExtensionTests
unRegister2.AddToUnregisterList(_unRegisterList); unRegister2.AddToUnregisterList(_unRegisterList);
unRegister3.AddToUnregisterList(_unRegisterList); unRegister3.AddToUnregisterList(_unRegisterList);
// 执行注销操作
_unRegisterList.UnRegisterAll(); _unRegisterList.UnRegisterAll();
Assert.That(invoked1, Is.True); Assert.That(invoked1, Is.True);
@ -62,23 +78,33 @@ public class UnRegisterListExtensionTests
Assert.That(invoked3, Is.True); Assert.That(invoked3, Is.True);
} }
/// <summary>
/// 验证UnRegisterAll方法在执行后会清空列表
/// </summary>
[Test] [Test]
public void UnRegisterAll_Should_Clear_List() public void UnRegisterAll_Should_Clear_List()
{ {
var unRegister = new DefaultUnRegister(() => { }); var unRegister = new DefaultUnRegister(() => { });
unRegister.AddToUnregisterList(_unRegisterList); unRegister.AddToUnregisterList(_unRegisterList);
// 执行注销操作
_unRegisterList.UnRegisterAll(); _unRegisterList.UnRegisterAll();
Assert.That(_unRegisterList.UnregisterList.Count, Is.EqualTo(0)); Assert.That(_unRegisterList.UnregisterList.Count, Is.EqualTo(0));
} }
/// <summary>
/// 验证UnRegisterAll方法在空列表情况下不会抛出异常
/// </summary>
[Test] [Test]
public void UnRegisterAll_Should_Not_Throw_When_Empty() public void UnRegisterAll_Should_Not_Throw_When_Empty()
{ {
Assert.DoesNotThrow(() => _unRegisterList.UnRegisterAll()); Assert.DoesNotThrow(() => _unRegisterList.UnRegisterAll());
} }
/// <summary>
/// 验证UnRegisterAll方法对每个元素只调用一次注销操作
/// </summary>
[Test] [Test]
public void UnRegisterAll_Should_Invoke_Once_Per_Element() public void UnRegisterAll_Should_Invoke_Once_Per_Element()
{ {
@ -87,13 +113,20 @@ public class UnRegisterListExtensionTests
unRegister.AddToUnregisterList(_unRegisterList); unRegister.AddToUnregisterList(_unRegisterList);
// 执行注销操作
_unRegisterList.UnRegisterAll(); _unRegisterList.UnRegisterAll();
Assert.That(callCount, Is.EqualTo(1)); Assert.That(callCount, Is.EqualTo(1));
} }
} }
/// <summary>
/// 测试用的UnRegisterList实现类用于验证扩展方法功能
/// </summary>
public class TestUnRegisterList : IUnRegisterList public class TestUnRegisterList : IUnRegisterList
{ {
/// <summary>
/// 获取或设置注销列表
/// </summary>
public IList<IUnRegister> UnregisterList { get; } = new List<IUnRegister>(); public IList<IUnRegister> UnregisterList { get; } = new List<IUnRegister>();
} }

View File

@ -6,9 +6,15 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.ioc; namespace GFramework.Core.Tests.ioc;
/// <summary>
/// 测试 IoC 容器功能的单元测试类
/// </summary>
[TestFixture] [TestFixture]
public class IocContainerTests public class IocContainerTests
{ {
/// <summary>
/// 在每个测试方法执行前进行设置
/// </summary>
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -26,6 +32,9 @@ public class IocContainerTests
private IocContainer _container = null!; private IocContainer _container = null!;
private readonly Dictionary<Type, object> _mockContextServices = new(); private readonly Dictionary<Type, object> _mockContextServices = new();
/// <summary>
/// 测试注册单例实例的功能
/// </summary>
[Test] [Test]
public void RegisterSingleton_Should_Register_Instance() public void RegisterSingleton_Should_Register_Instance()
{ {
@ -34,6 +43,9 @@ public class IocContainerTests
Assert.DoesNotThrow(() => _container.RegisterSingleton(instance)); Assert.DoesNotThrow(() => _container.RegisterSingleton(instance));
} }
/// <summary>
/// 测试重复注册单例时应抛出 InvalidOperationException 异常
/// </summary>
[Test] [Test]
public void RegisterSingleton_WithDuplicate_Should_ThrowInvalidOperationException() public void RegisterSingleton_WithDuplicate_Should_ThrowInvalidOperationException()
{ {
@ -45,6 +57,9 @@ public class IocContainerTests
Assert.Throws<InvalidOperationException>(() => _container.RegisterSingleton(instance2)); Assert.Throws<InvalidOperationException>(() => _container.RegisterSingleton(instance2));
} }
/// <summary>
/// 测试在容器冻结后注册单例时应抛出 InvalidOperationException 异常
/// </summary>
[Test] [Test]
public void RegisterSingleton_AfterFreeze_Should_ThrowInvalidOperationException() public void RegisterSingleton_AfterFreeze_Should_ThrowInvalidOperationException()
{ {
@ -54,6 +69,9 @@ public class IocContainerTests
Assert.Throws<InvalidOperationException>(() => _container.RegisterSingleton(instance)); Assert.Throws<InvalidOperationException>(() => _container.RegisterSingleton(instance));
} }
/// <summary>
/// 测试注册多样性实例到所有类型的功能
/// </summary>
[Test] [Test]
public void RegisterPlurality_Should_Register_Instance_To_All_Types() public void RegisterPlurality_Should_Register_Instance_To_All_Types()
{ {
@ -65,6 +83,9 @@ public class IocContainerTests
Assert.That(_container.Contains<IService>(), Is.True); Assert.That(_container.Contains<IService>(), Is.True);
} }
/// <summary>
/// 测试在容器冻结后注册多样性实例时应抛出 InvalidOperationException 异常
/// </summary>
[Test] [Test]
public void RegisterPlurality_AfterFreeze_Should_ThrowInvalidOperationException() public void RegisterPlurality_AfterFreeze_Should_ThrowInvalidOperationException()
{ {
@ -74,6 +95,9 @@ public class IocContainerTests
Assert.Throws<InvalidOperationException>(() => _container.RegisterPlurality(instance)); Assert.Throws<InvalidOperationException>(() => _container.RegisterPlurality(instance));
} }
/// <summary>
/// 测试泛型注册实例的功能
/// </summary>
[Test] [Test]
public void Register_Generic_Should_Register_Instance() public void Register_Generic_Should_Register_Instance()
{ {
@ -84,6 +108,9 @@ public class IocContainerTests
Assert.That(_container.Contains<TestService>(), Is.True); Assert.That(_container.Contains<TestService>(), Is.True);
} }
/// <summary>
/// 测试在容器冻结后使用泛型注册时应抛出 InvalidOperationException 异常
/// </summary>
[Test] [Test]
public void Register_Generic_AfterFreeze_Should_ThrowInvalidOperationException() public void Register_Generic_AfterFreeze_Should_ThrowInvalidOperationException()
{ {
@ -93,6 +120,9 @@ public class IocContainerTests
Assert.Throws<InvalidOperationException>(() => _container.Register(instance)); Assert.Throws<InvalidOperationException>(() => _container.Register(instance));
} }
/// <summary>
/// 测试按类型注册实例的功能
/// </summary>
[Test] [Test]
public void Register_Type_Should_Register_Instance() public void Register_Type_Should_Register_Instance()
{ {
@ -103,6 +133,9 @@ public class IocContainerTests
Assert.That(_container.Contains<TestService>(), Is.True); Assert.That(_container.Contains<TestService>(), Is.True);
} }
/// <summary>
/// 测试获取第一个实例的功能
/// </summary>
[Test] [Test]
public void Get_Should_Return_First_Instance() public void Get_Should_Return_First_Instance()
{ {
@ -115,6 +148,9 @@ public class IocContainerTests
Assert.That(result, Is.SameAs(instance)); Assert.That(result, Is.SameAs(instance));
} }
/// <summary>
/// 测试当没有实例时获取应返回 null 的功能
/// </summary>
[Test] [Test]
public void Get_WithNoInstances_Should_ReturnNull() public void Get_WithNoInstances_Should_ReturnNull()
{ {
@ -123,6 +159,9 @@ public class IocContainerTests
Assert.That(result, Is.Null); Assert.That(result, Is.Null);
} }
/// <summary>
/// 测试获取必需的单个实例的功能
/// </summary>
[Test] [Test]
public void GetRequired_Should_Return_Single_Instance() public void GetRequired_Should_Return_Single_Instance()
{ {
@ -135,12 +174,18 @@ public class IocContainerTests
Assert.That(result, Is.SameAs(instance)); Assert.That(result, Is.SameAs(instance));
} }
/// <summary>
/// 测试当没有实例时获取必需实例应抛出 InvalidOperationException 异常
/// </summary>
[Test] [Test]
public void GetRequired_WithNoInstances_Should_ThrowInvalidOperationException() public void GetRequired_WithNoInstances_Should_ThrowInvalidOperationException()
{ {
Assert.Throws<InvalidOperationException>(() => _container.GetRequired<TestService>()); Assert.Throws<InvalidOperationException>(() => _container.GetRequired<TestService>());
} }
/// <summary>
/// 测试当有多个实例时获取必需实例应抛出 InvalidOperationException 异常
/// </summary>
[Test] [Test]
public void GetRequired_WithMultipleInstances_Should_ThrowInvalidOperationException() public void GetRequired_WithMultipleInstances_Should_ThrowInvalidOperationException()
{ {
@ -150,6 +195,9 @@ public class IocContainerTests
Assert.Throws<InvalidOperationException>(() => _container.GetRequired<TestService>()); Assert.Throws<InvalidOperationException>(() => _container.GetRequired<TestService>());
} }
/// <summary>
/// 测试获取所有实例的功能
/// </summary>
[Test] [Test]
public void GetAll_Should_Return_All_Instances() public void GetAll_Should_Return_All_Instances()
{ {
@ -166,6 +214,9 @@ public class IocContainerTests
Assert.That(results, Does.Contain(instance2)); Assert.That(results, Does.Contain(instance2));
} }
/// <summary>
/// 测试当没有实例时获取所有实例应返回空数组的功能
/// </summary>
[Test] [Test]
public void GetAll_WithNoInstances_Should_Return_Empty_Array() public void GetAll_WithNoInstances_Should_Return_Empty_Array()
{ {
@ -174,6 +225,9 @@ public class IocContainerTests
Assert.That(results.Count, Is.EqualTo(0)); Assert.That(results.Count, Is.EqualTo(0));
} }
/// <summary>
/// 测试获取排序后的所有实例的功能
/// </summary>
[Test] [Test]
public void GetAllSorted_Should_Return_Sorted_Instances() public void GetAllSorted_Should_Return_Sorted_Instances()
{ {
@ -189,6 +243,9 @@ public class IocContainerTests
Assert.That(results[2].Priority, Is.EqualTo(3)); Assert.That(results[2].Priority, Is.EqualTo(3));
} }
/// <summary>
/// 测试当存在实例时检查包含关系应返回 true 的功能
/// </summary>
[Test] [Test]
public void Contains_WithExistingInstance_Should_ReturnTrue() public void Contains_WithExistingInstance_Should_ReturnTrue()
{ {
@ -198,12 +255,18 @@ public class IocContainerTests
Assert.That(_container.Contains<TestService>(), Is.True); Assert.That(_container.Contains<TestService>(), Is.True);
} }
/// <summary>
/// 测试当不存在实例时检查包含关系应返回 false 的功能
/// </summary>
[Test] [Test]
public void Contains_WithNoInstances_Should_ReturnFalse() public void Contains_WithNoInstances_Should_ReturnFalse()
{ {
Assert.That(_container.Contains<TestService>(), Is.False); Assert.That(_container.Contains<TestService>(), Is.False);
} }
/// <summary>
/// 测试当实例存在时检查实例包含关系应返回 true 的功能
/// </summary>
[Test] [Test]
public void ContainsInstance_WithExistingInstance_Should_ReturnTrue() public void ContainsInstance_WithExistingInstance_Should_ReturnTrue()
{ {
@ -213,6 +276,9 @@ public class IocContainerTests
Assert.That(_container.ContainsInstance(instance), Is.True); Assert.That(_container.ContainsInstance(instance), Is.True);
} }
/// <summary>
/// 测试当实例不存在时检查实例包含关系应返回 false 的功能
/// </summary>
[Test] [Test]
public void ContainsInstance_WithNonExistingInstance_Should_ReturnFalse() public void ContainsInstance_WithNonExistingInstance_Should_ReturnFalse()
{ {
@ -221,6 +287,9 @@ public class IocContainerTests
Assert.That(_container.ContainsInstance(instance), Is.False); Assert.That(_container.ContainsInstance(instance), Is.False);
} }
/// <summary>
/// 测试清除所有实例的功能
/// </summary>
[Test] [Test]
public void Clear_Should_Remove_All_Instances() public void Clear_Should_Remove_All_Instances()
{ {
@ -232,6 +301,9 @@ public class IocContainerTests
Assert.That(_container.Contains<TestService>(), Is.False); Assert.That(_container.Contains<TestService>(), Is.False);
} }
/// <summary>
/// 测试冻结容器以防止进一步注册的功能
/// </summary>
[Test] [Test]
public void Freeze_Should_Prevent_Further_Registrations() public void Freeze_Should_Prevent_Further_Registrations()
{ {
@ -243,6 +315,9 @@ public class IocContainerTests
Assert.Throws<InvalidOperationException>(() => _container.Register(instance2)); Assert.Throws<InvalidOperationException>(() => _container.Register(instance2));
} }
/// <summary>
/// 测试注册系统实例的功能
/// </summary>
[Test] [Test]
public void RegisterSystem_Should_Register_Instance() public void RegisterSystem_Should_Register_Instance()
{ {
@ -254,9 +329,18 @@ public class IocContainerTests
} }
} }
/// <summary>
/// 服务接口定义
/// </summary>
public interface IService; public interface IService;
/// <summary>
/// 测试服务类,实现 IService 接口
/// </summary>
public sealed class TestService : IService public sealed class TestService : IService
{ {
/// <summary>
/// 获取或设置优先级
/// </summary>
public int Priority { get; set; } public int Priority { get; set; }
} }

View File

@ -4,9 +4,16 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.logging; namespace GFramework.Core.Tests.logging;
/// <summary>
/// 测试ConsoleLogger类的功能和行为的单元测试类
/// </summary>
[TestFixture] [TestFixture]
public class ConsoleLoggerTests public class ConsoleLoggerTests
{ {
/// <summary>
/// 在每个测试方法执行前设置测试环境
/// 创建StringWriter和ConsoleLogger实例用于测试
/// </summary>
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -14,6 +21,10 @@ public class ConsoleLoggerTests
_logger = new ConsoleLogger("TestLogger", LogLevel.Info, _stringWriter, false); _logger = new ConsoleLogger("TestLogger", LogLevel.Info, _stringWriter, false);
} }
/// <summary>
/// 在每个测试方法执行后清理测试资源
/// 释放StringWriter资源
/// </summary>
[TearDown] [TearDown]
public void TearDown() public void TearDown()
{ {
@ -23,6 +34,10 @@ public class ConsoleLoggerTests
private StringWriter _stringWriter = null!; private StringWriter _stringWriter = null!;
private ConsoleLogger _logger = null!; private ConsoleLogger _logger = null!;
/// <summary>
/// 测试使用默认名称构造函数时是否正确使用根日志器名称
/// 验证当未指定名称时,日志器使用"ROOT"作为默认名称
/// </summary>
[Test] [Test]
public void Constructor_WithDefaultName_ShouldUseRootLoggerName() public void Constructor_WithDefaultName_ShouldUseRootLoggerName()
{ {
@ -31,6 +46,10 @@ public class ConsoleLoggerTests
Assert.That(defaultLogger.Name(), Is.EqualTo("ROOT")); Assert.That(defaultLogger.Name(), Is.EqualTo("ROOT"));
} }
/// <summary>
/// 测试使用自定义名称构造函数时是否正确使用自定义名称
/// 验证构造函数能够正确设置并返回指定的日志器名称
/// </summary>
[Test] [Test]
public void Constructor_WithCustomName_ShouldUseCustomName() public void Constructor_WithCustomName_ShouldUseCustomName()
{ {
@ -39,6 +58,10 @@ public class ConsoleLoggerTests
Assert.That(customLogger.Name(), Is.EqualTo("CustomLogger")); Assert.That(customLogger.Name(), Is.EqualTo("CustomLogger"));
} }
/// <summary>
/// 测试使用自定义最小级别构造函数时是否正确遵循最小日志级别
/// 验证只有达到或超过最小级别的日志消息才会被记录
/// </summary>
[Test] [Test]
public void Constructor_WithCustomMinLevel_ShouldRespectMinLevel() public void Constructor_WithCustomMinLevel_ShouldRespectMinLevel()
{ {
@ -52,6 +75,10 @@ public class ConsoleLoggerTests
Assert.That(output, Does.Not.Contain("TRACE")); Assert.That(output, Does.Not.Contain("TRACE"));
} }
/// <summary>
/// 测试使用自定义写入器构造函数时是否将日志写入到自定义写入器
/// 验证日志消息能够正确写入到指定的StringWriter中
/// </summary>
[Test] [Test]
public void Constructor_WithCustomWriter_ShouldWriteToCustomWriter() public void Constructor_WithCustomWriter_ShouldWriteToCustomWriter()
{ {
@ -61,6 +88,10 @@ public class ConsoleLoggerTests
Assert.That(output, Does.Contain("Test message")); Assert.That(output, Does.Contain("Test message"));
} }
/// <summary>
/// 测试写入操作是否包含时间戳信息
/// 验证每条日志消息都包含格式化的日期时间信息
/// </summary>
[Test] [Test]
public void Write_ShouldIncludeTimestamp() 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}\]")); Assert.That(output, Does.Match(@"\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}\]"));
} }
/// <summary>
/// 测试写入操作是否包含日志级别信息
/// 验证不同级别的日志消息都能正确显示对应的级别标识
/// </summary>
[Test] [Test]
public void Write_ShouldIncludeLevel() public void Write_ShouldIncludeLevel()
{ {
@ -84,6 +119,10 @@ public class ConsoleLoggerTests
Assert.That(output, Does.Contain("ERROR")); Assert.That(output, Does.Contain("ERROR"));
} }
/// <summary>
/// 测试写入操作是否包含日志器名称
/// 验证日志输出中包含创建时指定的日志器名称
/// </summary>
[Test] [Test]
public void Write_ShouldIncludeLoggerName() public void Write_ShouldIncludeLoggerName()
{ {
@ -93,6 +132,10 @@ public class ConsoleLoggerTests
Assert.That(output, Does.Contain("[TestLogger]")); Assert.That(output, Does.Contain("[TestLogger]"));
} }
/// <summary>
/// 测试写入操作在包含异常时是否正确包含异常信息
/// 验证异常的详细信息能够正确记录在日志中
/// </summary>
[Test] [Test]
public void Write_WithException_ShouldIncludeException() public void Write_WithException_ShouldIncludeException()
{ {
@ -104,6 +147,10 @@ public class ConsoleLoggerTests
Assert.That(output, Does.Contain("Test exception")); Assert.That(output, Does.Contain("Test exception"));
} }
/// <summary>
/// 测试写入多行日志时是否正确格式化
/// 验证多条日志消息能够正确分行显示且包含正确的级别信息
/// </summary>
[Test] [Test]
public void Write_WithMultipleLines_ShouldFormatCorrectly() public void Write_WithMultipleLines_ShouldFormatCorrectly()
{ {
@ -120,6 +167,10 @@ public class ConsoleLoggerTests
Assert.That(lines[2], Does.Contain("ERROR")); Assert.That(lines[2], Does.Contain("ERROR"));
} }
/// <summary>
/// 测试写入格式化消息时是否正确格式化
/// 验证带参数的消息格式化功能正常工作
/// </summary>
[Test] [Test]
public void Write_WithFormattedMessage_ShouldFormatCorrectly() public void Write_WithFormattedMessage_ShouldFormatCorrectly()
{ {
@ -129,6 +180,10 @@ public class ConsoleLoggerTests
Assert.That(output, Does.Contain("Value: 42")); Assert.That(output, Does.Contain("Value: 42"));
} }
/// <summary>
/// 测试写入操作是否遵循最小日志级别限制
/// 验证低于最小级别的日志消息不会被记录
/// </summary>
[Test] [Test]
public void Write_ShouldRespectMinLevel() public void Write_ShouldRespectMinLevel()
{ {
@ -142,6 +197,10 @@ public class ConsoleLoggerTests
Assert.That(output, Does.Not.Contain("Trace message")); Assert.That(output, Does.Not.Contain("Trace message"));
} }
/// <summary>
/// 测试启用颜色功能时是否不影响输出内容
/// 验证即使颜色功能被禁用,日志内容仍然正确记录
/// </summary>
[Test] [Test]
public void Write_WithColorsEnabled_ShouldNotAffectOutputContent() public void Write_WithColorsEnabled_ShouldNotAffectOutputContent()
{ {
@ -153,6 +212,10 @@ public class ConsoleLoggerTests
Assert.That(output, Does.Contain("Colored message")); Assert.That(output, Does.Contain("Colored message"));
} }
/// <summary>
/// 测试所有日志级别是否都能正确格式化
/// 验证从Trace到Fatal的所有日志级别都能正确显示
/// </summary>
[Test] [Test]
public void Write_AllLogLevels_ShouldFormatCorrectly() public void Write_AllLogLevels_ShouldFormatCorrectly()
{ {
@ -170,6 +233,10 @@ public class ConsoleLoggerTests
Assert.That(output, Does.Contain("FATAL")); Assert.That(output, Does.Contain("FATAL"));
} }
/// <summary>
/// 测试写入嵌套异常时是否包含完整的异常信息
/// 验证嵌套异常的所有层级信息都能被正确记录
/// </summary>
[Test] [Test]
public void Write_WithNestedException_ShouldIncludeFullException() public void Write_WithNestedException_ShouldIncludeFullException()
{ {
@ -184,6 +251,10 @@ public class ConsoleLoggerTests
Assert.That(output, Does.Contain("Inner exception")); Assert.That(output, Does.Contain("Inner exception"));
} }
/// <summary>
/// 测试使用空写入器时是否不会抛出异常
/// 验证当传入null写入器时日志器能够安全处理而不崩溃
/// </summary>
[Test] [Test]
public void Write_WithNullWriter_ShouldNotThrow() public void Write_WithNullWriter_ShouldNotThrow()
{ {
@ -192,6 +263,10 @@ public class ConsoleLoggerTests
Assert.DoesNotThrow(() => logger.Info("Test message")); Assert.DoesNotThrow(() => logger.Info("Test message"));
} }
/// <summary>
/// 测试写入空消息时是否仍能正常写入
/// 验证即使消息为空字符串,日志框架仍能生成包含其他信息的完整日志条目
/// </summary>
[Test] [Test]
public void Write_WithEmptyMessage_ShouldStillWrite() public void Write_WithEmptyMessage_ShouldStillWrite()
{ {

View File

@ -4,9 +4,15 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.logging; namespace GFramework.Core.Tests.logging;
/// <summary>
/// 测试LoggerFactory相关功能的测试类
/// </summary>
[TestFixture] [TestFixture]
public class LoggerFactoryTests public class LoggerFactoryTests
{ {
/// <summary>
/// 测试ConsoleLoggerFactory的GetLogger方法是否返回ConsoleLogger实例
/// </summary>
[Test] [Test]
public void ConsoleLoggerFactory_GetLogger_ShouldReturnConsoleLogger() public void ConsoleLoggerFactory_GetLogger_ShouldReturnConsoleLogger()
{ {
@ -18,6 +24,9 @@ public class LoggerFactoryTests
Assert.That(logger.Name(), Is.EqualTo("TestLogger")); Assert.That(logger.Name(), Is.EqualTo("TestLogger"));
} }
/// <summary>
/// 测试ConsoleLoggerFactory使用不同名称获取不同的logger实例
/// </summary>
[Test] [Test]
public void ConsoleLoggerFactory_GetLogger_WithDifferentNames_ShouldReturnDifferentLoggers() public void ConsoleLoggerFactory_GetLogger_WithDifferentNames_ShouldReturnDifferentLoggers()
{ {
@ -29,6 +38,9 @@ public class LoggerFactoryTests
Assert.That(logger2.Name(), Is.EqualTo("Logger2")); Assert.That(logger2.Name(), Is.EqualTo("Logger2"));
} }
/// <summary>
/// 测试ConsoleLoggerFactory使用默认最小级别时的行为默认为Info级别
/// </summary>
[Test] [Test]
public void ConsoleLoggerFactory_GetLogger_WithDefaultMinLevel_ShouldUseInfo() public void ConsoleLoggerFactory_GetLogger_WithDefaultMinLevel_ShouldUseInfo()
{ {
@ -38,6 +50,7 @@ public class LoggerFactoryTests
var stringWriter = new StringWriter(); var stringWriter = new StringWriter();
var testLogger = new ConsoleLogger("TestLogger", LogLevel.Info, stringWriter, false); var testLogger = new ConsoleLogger("TestLogger", LogLevel.Info, stringWriter, false);
// 验证Debug消息不会被记录但Info消息会被记录
testLogger.Debug("Debug message"); testLogger.Debug("Debug message");
testLogger.Info("Info message"); testLogger.Info("Info message");
@ -46,6 +59,9 @@ public class LoggerFactoryTests
Assert.That(output, Does.Contain("Info message")); Assert.That(output, Does.Contain("Info message"));
} }
/// <summary>
/// 测试ConsoleLoggerFactoryProvider创建logger时使用提供者的最小级别设置
/// </summary>
[Test] [Test]
public void ConsoleLoggerFactoryProvider_CreateLogger_ShouldReturnLoggerWithProviderMinLevel() public void ConsoleLoggerFactoryProvider_CreateLogger_ShouldReturnLoggerWithProviderMinLevel()
{ {
@ -55,6 +71,7 @@ public class LoggerFactoryTests
var stringWriter = new StringWriter(); var stringWriter = new StringWriter();
var testLogger = new ConsoleLogger("TestLogger", LogLevel.Debug, stringWriter, false); var testLogger = new ConsoleLogger("TestLogger", LogLevel.Debug, stringWriter, false);
// 验证Debug消息会被记录但Trace消息不会被记录
testLogger.Debug("Debug message"); testLogger.Debug("Debug message");
testLogger.Trace("Trace message"); testLogger.Trace("Trace message");
@ -63,6 +80,9 @@ public class LoggerFactoryTests
Assert.That(output, Does.Not.Contain("Trace message")); Assert.That(output, Does.Not.Contain("Trace message"));
} }
/// <summary>
/// 测试ConsoleLoggerFactoryProvider创建logger时使用提供的名称
/// </summary>
[Test] [Test]
public void ConsoleLoggerFactoryProvider_CreateLogger_ShouldUseProvidedName() public void ConsoleLoggerFactoryProvider_CreateLogger_ShouldUseProvidedName()
{ {
@ -72,6 +92,9 @@ public class LoggerFactoryTests
Assert.That(logger.Name(), Is.EqualTo("MyLogger")); Assert.That(logger.Name(), Is.EqualTo("MyLogger"));
} }
/// <summary>
/// 测试LoggerFactoryResolver的Provider属性是否有默认值
/// </summary>
[Test] [Test]
public void LoggerFactoryResolver_Provider_ShouldHaveDefaultValue() public void LoggerFactoryResolver_Provider_ShouldHaveDefaultValue()
{ {
@ -79,6 +102,9 @@ public class LoggerFactoryTests
Assert.That(LoggerFactoryResolver.Provider, Is.InstanceOf<ConsoleLoggerFactoryProvider>()); Assert.That(LoggerFactoryResolver.Provider, Is.InstanceOf<ConsoleLoggerFactoryProvider>());
} }
/// <summary>
/// 测试LoggerFactoryResolver的Provider属性可以被更改
/// </summary>
[Test] [Test]
public void LoggerFactoryResolver_Provider_CanBeChanged() public void LoggerFactoryResolver_Provider_CanBeChanged()
{ {
@ -92,12 +118,18 @@ public class LoggerFactoryTests
LoggerFactoryResolver.Provider = originalProvider; LoggerFactoryResolver.Provider = originalProvider;
} }
/// <summary>
/// 测试LoggerFactoryResolver的MinLevel属性是否有默认值
/// </summary>
[Test] [Test]
public void LoggerFactoryResolver_MinLevel_ShouldHaveDefaultValue() public void LoggerFactoryResolver_MinLevel_ShouldHaveDefaultValue()
{ {
Assert.That(LoggerFactoryResolver.MinLevel, Is.EqualTo(LogLevel.Info)); Assert.That(LoggerFactoryResolver.MinLevel, Is.EqualTo(LogLevel.Info));
} }
/// <summary>
/// 测试LoggerFactoryResolver的MinLevel属性可以被更改
/// </summary>
[Test] [Test]
public void LoggerFactoryResolver_MinLevel_CanBeChanged() public void LoggerFactoryResolver_MinLevel_CanBeChanged()
{ {
@ -110,6 +142,9 @@ public class LoggerFactoryTests
LoggerFactoryResolver.MinLevel = originalLevel; LoggerFactoryResolver.MinLevel = originalLevel;
} }
/// <summary>
/// 测试ConsoleLoggerFactoryProvider的MinLevel属性是否有默认值
/// </summary>
[Test] [Test]
public void ConsoleLoggerFactoryProvider_MinLevel_ShouldHaveDefaultValue() public void ConsoleLoggerFactoryProvider_MinLevel_ShouldHaveDefaultValue()
{ {
@ -118,6 +153,9 @@ public class LoggerFactoryTests
Assert.That(provider.MinLevel, Is.EqualTo(LogLevel.Info)); Assert.That(provider.MinLevel, Is.EqualTo(LogLevel.Info));
} }
/// <summary>
/// 测试ConsoleLoggerFactoryProvider的MinLevel属性可以被更改
/// </summary>
[Test] [Test]
public void ConsoleLoggerFactoryProvider_MinLevel_CanBeChanged() public void ConsoleLoggerFactoryProvider_MinLevel_CanBeChanged()
{ {
@ -128,6 +166,9 @@ public class LoggerFactoryTests
Assert.That(provider.MinLevel, Is.EqualTo(LogLevel.Debug)); Assert.That(provider.MinLevel, Is.EqualTo(LogLevel.Debug));
} }
/// <summary>
/// 测试LoggerFactoryResolver的Provider创建logger时使用提供者设置
/// </summary>
[Test] [Test]
public void LoggerFactoryResolver_Provider_CreateLogger_ShouldUseProviderSettings() public void LoggerFactoryResolver_Provider_CreateLogger_ShouldUseProviderSettings()
{ {
@ -141,6 +182,7 @@ public class LoggerFactoryTests
var stringWriter = new StringWriter(); var stringWriter = new StringWriter();
var testLogger = new ConsoleLogger("TestLogger", LogLevel.Warning, stringWriter, false); var testLogger = new ConsoleLogger("TestLogger", LogLevel.Warning, stringWriter, false);
// 验证Warn消息会被记录但Info消息不会被记录
testLogger.Warn("Warn message"); testLogger.Warn("Warn message");
testLogger.Info("Info message"); testLogger.Info("Info message");
@ -151,6 +193,9 @@ public class LoggerFactoryTests
LoggerFactoryResolver.Provider = originalProvider; LoggerFactoryResolver.Provider = originalProvider;
} }
/// <summary>
/// 测试LoggerFactoryResolver的MinLevel属性影响新创建的logger
/// </summary>
[Test] [Test]
public void LoggerFactoryResolver_MinLevel_AffectsNewLoggers() public void LoggerFactoryResolver_MinLevel_AffectsNewLoggers()
{ {
@ -164,6 +209,7 @@ public class LoggerFactoryTests
var stringWriter = new StringWriter(); var stringWriter = new StringWriter();
var testLogger = new ConsoleLogger("TestLogger", LogLevel.Error, stringWriter, false); var testLogger = new ConsoleLogger("TestLogger", LogLevel.Error, stringWriter, false);
// 验证Error消息会被记录但Warn消息不会被记录
testLogger.Error("Error message"); testLogger.Error("Error message");
testLogger.Warn("Warn message"); testLogger.Warn("Warn message");
@ -174,6 +220,9 @@ public class LoggerFactoryTests
LoggerFactoryResolver.MinLevel = originalMinLevel; LoggerFactoryResolver.MinLevel = originalMinLevel;
} }
/// <summary>
/// 测试ConsoleLoggerFactory创建的多个logger实例是独立的
/// </summary>
[Test] [Test]
public void ConsoleLoggerFactory_MultipleLoggers_ShouldBeIndependent() public void ConsoleLoggerFactory_MultipleLoggers_ShouldBeIndependent()
{ {
@ -185,6 +234,9 @@ public class LoggerFactoryTests
Assert.That(logger2.Name(), Is.EqualTo("Logger2")); Assert.That(logger2.Name(), Is.EqualTo("Logger2"));
} }
/// <summary>
/// 测试ConsoleLoggerFactoryProvider的MinLevel不会影响已创建的logger
/// </summary>
[Test] [Test]
public void ConsoleLoggerFactoryProvider_MinLevel_DoesNotAffectCreatedLogger() public void ConsoleLoggerFactoryProvider_MinLevel_DoesNotAffectCreatedLogger()
{ {
@ -194,6 +246,7 @@ public class LoggerFactoryTests
var stringWriter = new StringWriter(); var stringWriter = new StringWriter();
var testLogger = new ConsoleLogger("TestLogger", LogLevel.Error, stringWriter, false); var testLogger = new ConsoleLogger("TestLogger", LogLevel.Error, stringWriter, false);
// 验证Error和Fatal消息都会被记录
testLogger.Error("Error message"); testLogger.Error("Error message");
testLogger.Fatal("Fatal message"); testLogger.Fatal("Fatal message");

View File

@ -4,9 +4,16 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.logging; namespace GFramework.Core.Tests.logging;
/// <summary>
/// 测试Logger功能的单元测试类
/// </summary>
[TestFixture] [TestFixture]
public class LoggerTests public class LoggerTests
{ {
/// <summary>
/// 在每个测试方法执行前设置测试环境
/// 创建一个新的TestLogger实例名称为"TestLogger"最小日志级别为Info
/// </summary>
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -15,6 +22,9 @@ public class LoggerTests
private TestLogger _logger = null!; private TestLogger _logger = null!;
/// <summary>
/// 验证Name方法是否正确返回Logger的名称
/// </summary>
[Test] [Test]
public void Name_Should_ReturnLoggerName() public void Name_Should_ReturnLoggerName()
{ {
@ -23,6 +33,9 @@ public class LoggerTests
Assert.That(name, Is.EqualTo("TestLogger")); Assert.That(name, Is.EqualTo("TestLogger"));
} }
/// <summary>
/// 验证当使用默认名称时Name方法是否返回根Logger名称"ROOT"
/// </summary>
[Test] [Test]
public void Name_WithDefaultName_Should_ReturnRootLoggerName() public void Name_WithDefaultName_Should_ReturnRootLoggerName()
{ {
@ -31,42 +44,63 @@ public class LoggerTests
Assert.That(defaultLogger.Name(), Is.EqualTo("ROOT")); Assert.That(defaultLogger.Name(), Is.EqualTo("ROOT"));
} }
/// <summary>
/// 验证当最小日志级别为Info时IsTraceEnabled方法是否返回false
/// </summary>
[Test] [Test]
public void IsTraceEnabled_WithInfoMinLevel_Should_ReturnFalse() public void IsTraceEnabled_WithInfoMinLevel_Should_ReturnFalse()
{ {
Assert.That(_logger.IsTraceEnabled(), Is.False); Assert.That(_logger.IsTraceEnabled(), Is.False);
} }
/// <summary>
/// 验证当最小日志级别为Info时IsDebugEnabled方法是否返回false
/// </summary>
[Test] [Test]
public void IsDebugEnabled_WithInfoMinLevel_Should_ReturnFalse() public void IsDebugEnabled_WithInfoMinLevel_Should_ReturnFalse()
{ {
Assert.That(_logger.IsDebugEnabled(), Is.False); Assert.That(_logger.IsDebugEnabled(), Is.False);
} }
/// <summary>
/// 验证当最小日志级别为Info时IsInfoEnabled方法是否返回true
/// </summary>
[Test] [Test]
public void IsInfoEnabled_WithInfoMinLevel_Should_ReturnTrue() public void IsInfoEnabled_WithInfoMinLevel_Should_ReturnTrue()
{ {
Assert.That(_logger.IsInfoEnabled(), Is.True); Assert.That(_logger.IsInfoEnabled(), Is.True);
} }
/// <summary>
/// 验证当最小日志级别为Info时IsWarnEnabled方法是否返回true
/// </summary>
[Test] [Test]
public void IsWarnEnabled_WithInfoMinLevel_Should_ReturnTrue() public void IsWarnEnabled_WithInfoMinLevel_Should_ReturnTrue()
{ {
Assert.That(_logger.IsWarnEnabled(), Is.True); Assert.That(_logger.IsWarnEnabled(), Is.True);
} }
/// <summary>
/// 验证当最小日志级别为Info时IsErrorEnabled方法是否返回true
/// </summary>
[Test] [Test]
public void IsErrorEnabled_WithInfoMinLevel_Should_ReturnTrue() public void IsErrorEnabled_WithInfoMinLevel_Should_ReturnTrue()
{ {
Assert.That(_logger.IsErrorEnabled(), Is.True); Assert.That(_logger.IsErrorEnabled(), Is.True);
} }
/// <summary>
/// 验证当最小日志级别为Info时IsFatalEnabled方法是否返回true
/// </summary>
[Test] [Test]
public void IsFatalEnabled_WithInfoMinLevel_Should_ReturnTrue() public void IsFatalEnabled_WithInfoMinLevel_Should_ReturnTrue()
{ {
Assert.That(_logger.IsFatalEnabled(), Is.True); Assert.That(_logger.IsFatalEnabled(), Is.True);
} }
/// <summary>
/// 验证IsEnabledForLevel方法对于不同日志级别的返回值是否正确
/// </summary>
[Test] [Test]
public void IsEnabledForLevel_WithValidLevel_Should_ReturnCorrectResult() public void IsEnabledForLevel_WithValidLevel_Should_ReturnCorrectResult()
{ {
@ -78,12 +112,18 @@ public class LoggerTests
Assert.That(_logger.IsEnabledForLevel(LogLevel.Fatal), Is.True); Assert.That(_logger.IsEnabledForLevel(LogLevel.Fatal), Is.True);
} }
/// <summary>
/// 验证当传入无效的日志级别时IsEnabledForLevel方法是否会抛出ArgumentException异常
/// </summary>
[Test] [Test]
public void IsEnabledForLevel_WithInvalidLevel_Should_ThrowArgumentException() public void IsEnabledForLevel_WithInvalidLevel_Should_ThrowArgumentException()
{ {
Assert.Throws<ArgumentException>(() => { _logger.IsEnabledForLevel((LogLevel)999); }); Assert.Throws<ArgumentException>(() => { _logger.IsEnabledForLevel((LogLevel)999); });
} }
/// <summary>
/// 验证当Trace级别被禁用时Trace方法不会写入日志
/// </summary>
[Test] [Test]
public void Trace_ShouldNotWrite_WhenTraceDisabled() public void Trace_ShouldNotWrite_WhenTraceDisabled()
{ {
@ -92,6 +132,9 @@ public class LoggerTests
Assert.That(_logger.Logs.Count, Is.EqualTo(0)); Assert.That(_logger.Logs.Count, Is.EqualTo(0));
} }
/// <summary>
/// 验证当Trace级别被禁用时带格式化参数的Trace方法不会写入日志
/// </summary>
[Test] [Test]
public void Trace_WithFormat_ShouldNotWrite_WhenTraceDisabled() public void Trace_WithFormat_ShouldNotWrite_WhenTraceDisabled()
{ {
@ -100,6 +143,9 @@ public class LoggerTests
Assert.That(_logger.Logs.Count, Is.EqualTo(0)); Assert.That(_logger.Logs.Count, Is.EqualTo(0));
} }
/// <summary>
/// 验证当Trace级别被禁用时带两个参数的Trace方法不会写入日志
/// </summary>
[Test] [Test]
public void Trace_WithTwoArgs_ShouldNotWrite_WhenTraceDisabled() public void Trace_WithTwoArgs_ShouldNotWrite_WhenTraceDisabled()
{ {
@ -108,6 +154,9 @@ public class LoggerTests
Assert.That(_logger.Logs.Count, Is.EqualTo(0)); Assert.That(_logger.Logs.Count, Is.EqualTo(0));
} }
/// <summary>
/// 验证当Trace级别被禁用时带异常参数的Trace方法不会写入日志
/// </summary>
[Test] [Test]
public void Trace_WithException_ShouldNotWrite_WhenTraceDisabled() public void Trace_WithException_ShouldNotWrite_WhenTraceDisabled()
{ {
@ -117,6 +166,9 @@ public class LoggerTests
Assert.That(_logger.Logs.Count, Is.EqualTo(0)); Assert.That(_logger.Logs.Count, Is.EqualTo(0));
} }
/// <summary>
/// 验证当Debug级别被禁用时Debug方法不会写入日志
/// </summary>
[Test] [Test]
public void Debug_ShouldNotWrite_WhenDebugDisabled() public void Debug_ShouldNotWrite_WhenDebugDisabled()
{ {
@ -125,6 +177,9 @@ public class LoggerTests
Assert.That(_logger.Logs.Count, Is.EqualTo(0)); Assert.That(_logger.Logs.Count, Is.EqualTo(0));
} }
/// <summary>
/// 验证当Debug级别被禁用时带格式化参数的Debug方法不会写入日志
/// </summary>
[Test] [Test]
public void Debug_WithFormat_ShouldNotWrite_WhenDebugDisabled() public void Debug_WithFormat_ShouldNotWrite_WhenDebugDisabled()
{ {
@ -133,6 +188,9 @@ public class LoggerTests
Assert.That(_logger.Logs.Count, Is.EqualTo(0)); Assert.That(_logger.Logs.Count, Is.EqualTo(0));
} }
/// <summary>
/// 验证当Info级别启用时Info方法会正确写入日志
/// </summary>
[Test] [Test]
public void Info_ShouldWrite_WhenInfoEnabled() public void Info_ShouldWrite_WhenInfoEnabled()
{ {
@ -144,6 +202,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Exception, Is.Null); Assert.That(_logger.Logs[0].Exception, Is.Null);
} }
/// <summary>
/// 验证带格式化参数的Info方法会正确写入格式化后的消息
/// </summary>
[Test] [Test]
public void Info_WithFormat_ShouldWriteFormattedMessage() public void Info_WithFormat_ShouldWriteFormattedMessage()
{ {
@ -153,6 +214,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted message")); Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted message"));
} }
/// <summary>
/// 验证带两个参数的Info方法会正确写入格式化后的消息
/// </summary>
[Test] [Test]
public void Info_WithTwoArgs_ShouldWriteFormattedMessage() public void Info_WithTwoArgs_ShouldWriteFormattedMessage()
{ {
@ -162,6 +226,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted arg1 and arg2")); Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted arg1 and arg2"));
} }
/// <summary>
/// 验证带多个参数的Info方法会正确写入格式化后的消息
/// </summary>
[Test] [Test]
public void Info_WithMultipleArgs_ShouldWriteFormattedMessage() public void Info_WithMultipleArgs_ShouldWriteFormattedMessage()
{ {
@ -171,6 +238,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted arg1, arg2, arg3")); Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted arg1, arg2, arg3"));
} }
/// <summary>
/// 验证带异常参数的Info方法会正确写入消息和异常
/// </summary>
[Test] [Test]
public void Info_WithException_ShouldWriteMessageAndException() public void Info_WithException_ShouldWriteMessageAndException()
{ {
@ -182,6 +252,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Exception, Is.SameAs(exception)); Assert.That(_logger.Logs[0].Exception, Is.SameAs(exception));
} }
/// <summary>
/// 验证当Warn级别启用时Warn方法会正确写入日志
/// </summary>
[Test] [Test]
public void Warn_ShouldWrite_WhenWarnEnabled() public void Warn_ShouldWrite_WhenWarnEnabled()
{ {
@ -192,6 +265,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Warn message")); Assert.That(_logger.Logs[0].Message, Is.EqualTo("Warn message"));
} }
/// <summary>
/// 验证带格式化参数的Warn方法会正确写入格式化后的消息
/// </summary>
[Test] [Test]
public void Warn_WithFormat_ShouldWriteFormattedMessage() public void Warn_WithFormat_ShouldWriteFormattedMessage()
{ {
@ -201,6 +277,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted message")); Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted message"));
} }
/// <summary>
/// 验证带异常参数的Warn方法会正确写入消息和异常
/// </summary>
[Test] [Test]
public void Warn_WithException_ShouldWriteMessageAndException() public void Warn_WithException_ShouldWriteMessageAndException()
{ {
@ -211,6 +290,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Exception, Is.SameAs(exception)); Assert.That(_logger.Logs[0].Exception, Is.SameAs(exception));
} }
/// <summary>
/// 验证当Error级别启用时Error方法会正确写入日志
/// </summary>
[Test] [Test]
public void Error_ShouldWrite_WhenErrorEnabled() public void Error_ShouldWrite_WhenErrorEnabled()
{ {
@ -221,6 +303,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Error message")); Assert.That(_logger.Logs[0].Message, Is.EqualTo("Error message"));
} }
/// <summary>
/// 验证带格式化参数的Error方法会正确写入格式化后的消息
/// </summary>
[Test] [Test]
public void Error_WithFormat_ShouldWriteFormattedMessage() public void Error_WithFormat_ShouldWriteFormattedMessage()
{ {
@ -230,6 +315,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted message")); Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted message"));
} }
/// <summary>
/// 验证带异常参数的Error方法会正确写入消息和异常
/// </summary>
[Test] [Test]
public void Error_WithException_ShouldWriteMessageAndException() public void Error_WithException_ShouldWriteMessageAndException()
{ {
@ -240,6 +328,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Exception, Is.SameAs(exception)); Assert.That(_logger.Logs[0].Exception, Is.SameAs(exception));
} }
/// <summary>
/// 验证当Fatal级别启用时Fatal方法会正确写入日志
/// </summary>
[Test] [Test]
public void Fatal_ShouldWrite_WhenFatalEnabled() public void Fatal_ShouldWrite_WhenFatalEnabled()
{ {
@ -250,6 +341,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Fatal message")); Assert.That(_logger.Logs[0].Message, Is.EqualTo("Fatal message"));
} }
/// <summary>
/// 验证带格式化参数的Fatal方法会正确写入格式化后的消息
/// </summary>
[Test] [Test]
public void Fatal_WithFormat_ShouldWriteFormattedMessage() public void Fatal_WithFormat_ShouldWriteFormattedMessage()
{ {
@ -259,6 +353,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted message")); Assert.That(_logger.Logs[0].Message, Is.EqualTo("Formatted message"));
} }
/// <summary>
/// 验证带异常参数的Fatal方法会正确写入消息和异常
/// </summary>
[Test] [Test]
public void Fatal_WithException_ShouldWriteMessageAndException() public void Fatal_WithException_ShouldWriteMessageAndException()
{ {
@ -269,6 +366,9 @@ public class LoggerTests
Assert.That(_logger.Logs[0].Exception, Is.SameAs(exception)); Assert.That(_logger.Logs[0].Exception, Is.SameAs(exception));
} }
/// <summary>
/// 验证多次调用日志方法会累积日志条目
/// </summary>
[Test] [Test]
public void MultipleLogCalls_ShouldAccumulateLogs() public void MultipleLogCalls_ShouldAccumulateLogs()
{ {
@ -282,6 +382,9 @@ public class LoggerTests
Assert.That(_logger.Logs[2].Message, Is.EqualTo("Message 3")); Assert.That(_logger.Logs[2].Message, Is.EqualTo("Message 3"));
} }
/// <summary>
/// 验证当最小日志级别设置为Trace时所有级别的日志都会被启用
/// </summary>
[Test] [Test]
public void Logger_WithTraceMinLevel_ShouldEnableAllLevels() public void Logger_WithTraceMinLevel_ShouldEnableAllLevels()
{ {
@ -297,6 +400,9 @@ public class LoggerTests
Assert.That(traceLogger.Logs.Count, Is.EqualTo(6)); Assert.That(traceLogger.Logs.Count, Is.EqualTo(6));
} }
/// <summary>
/// 验证当最小日志级别设置为Fatal时只有Fatal级别的日志会被启用
/// </summary>
[Test] [Test]
public void Logger_WithFatalMinLevel_ShouldDisableAllButFatal() public void Logger_WithFatalMinLevel_ShouldDisableAllButFatal()
{ {
@ -314,18 +420,41 @@ public class LoggerTests
} }
} }
/// <summary>
/// 测试用的日志记录器实现类继承自AbstractLogger
/// </summary>
public sealed class TestLogger : AbstractLogger 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) public TestLogger(string? name = null, LogLevel minLevel = LogLevel.Info) : base(name, minLevel)
{ {
} }
/// <summary>
/// 获取记录的日志条目列表
/// </summary>
public List<LogEntry> Logs { get; } = new(); 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) protected override void Write(LogLevel level, string message, Exception? exception)
{ {
Logs.Add(new LogEntry(level, message, 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); public sealed record LogEntry(LogLevel Level, string Message, Exception? Exception);
} }

View File

@ -4,17 +4,29 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.pool; namespace GFramework.Core.Tests.pool;
/// <summary>
/// 对象池功能测试类,用于验证对象池的基本操作和行为
/// </summary>
[TestFixture] [TestFixture]
public class ObjectPoolTests public class ObjectPoolTests
{ {
/// <summary>
/// 测试初始化方法,在每个测试方法执行前设置测试环境
/// </summary>
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
_pool = new TestObjectPool(); _pool = new TestObjectPool();
} }
/// <summary>
/// 测试用的对象池实例
/// </summary>
private TestObjectPool _pool = null!; private TestObjectPool _pool = null!;
/// <summary>
/// 验证当对象池为空时Acquire方法应该创建新对象
/// </summary>
[Test] [Test]
public void Acquire_Should_Create_New_Object_When_Pool_Empty() public void Acquire_Should_Create_New_Object_When_Pool_Empty()
{ {
@ -25,6 +37,9 @@ public class ObjectPoolTests
Assert.That(obj.OnAcquireCalled, Is.True); Assert.That(obj.OnAcquireCalled, Is.True);
} }
/// <summary>
/// 验证Acquire方法应该返回池中的可用对象
/// </summary>
[Test] [Test]
public void Acquire_Should_Return_Pooled_Object() public void Acquire_Should_Return_Pooled_Object()
{ {
@ -40,6 +55,9 @@ public class ObjectPoolTests
Assert.That(obj2.OnAcquireCalled, Is.True); Assert.That(obj2.OnAcquireCalled, Is.True);
} }
/// <summary>
/// 验证Release方法应该调用对象的OnRelease回调
/// </summary>
[Test] [Test]
public void Release_Should_Call_OnRelease() public void Release_Should_Call_OnRelease()
{ {
@ -50,6 +68,9 @@ public class ObjectPoolTests
Assert.That(obj.OnReleaseCalled, Is.True); Assert.That(obj.OnReleaseCalled, Is.True);
} }
/// <summary>
/// 验证Clear方法应该销毁所有对象
/// </summary>
[Test] [Test]
public void Clear_Should_Destroy_All_Objects() public void Clear_Should_Destroy_All_Objects()
{ {
@ -65,6 +86,9 @@ public class ObjectPoolTests
Assert.That(obj2.OnPoolDestroyCalled, Is.True); Assert.That(obj2.OnPoolDestroyCalled, Is.True);
} }
/// <summary>
/// 验证多个池键应该相互独立
/// </summary>
[Test] [Test]
public void Multiple_Pools_Should_Be_Independent() public void Multiple_Pools_Should_Be_Independent()
{ {
@ -80,6 +104,9 @@ public class ObjectPoolTests
Assert.That(obj4, Is.Not.SameAs(obj2)); Assert.That(obj4, Is.Not.SameAs(obj2));
} }
/// <summary>
/// 验证OnAcquire回调应该在新对象和池中对象上都被调用
/// </summary>
[Test] [Test]
public void OnAcquire_Should_Be_Called_On_New_And_Pooled_Objects() 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> public class TestObjectPool : AbstractObjectPoolSystem<string, TestPoolableObject>
{ {
/// <summary>
/// 创建新的池化对象
/// </summary>
/// <param name="key">用于标识对象的键</param>
/// <returns>新创建的TestPoolableObject实例</returns>
protected override TestPoolableObject Create(string key) protected override TestPoolableObject Create(string key)
{ {
return new TestPoolableObject { PoolKey = key }; return new TestPoolableObject { PoolKey = key };
} }
/// <summary>
/// 初始化方法,用于对象池初始化时的操作
/// </summary>
protected override void OnInit() protected override void OnInit()
{ {
} }
} }
/// <summary>
/// 测试用池化对象类实现了IPoolableObject接口
/// </summary>
public class TestPoolableObject : IPoolableObject public class TestPoolableObject : IPoolableObject
{ {
/// <summary>
/// 获取或设置对象的池键
/// </summary>
public string PoolKey { get; set; } = string.Empty; public string PoolKey { get; set; } = string.Empty;
/// <summary>
/// 获取或设置测试用的整数值
/// </summary>
public int TestValue { get; set; } public int TestValue { get; set; }
/// <summary>
/// 获取或设置OnAcquire方法是否被调用的标志
/// </summary>
public bool OnAcquireCalled { get; set; } public bool OnAcquireCalled { get; set; }
/// <summary>
/// 获取或设置OnRelease方法是否被调用的标志
/// </summary>
public bool OnReleaseCalled { get; set; } public bool OnReleaseCalled { get; set; }
/// <summary>
/// 获取或设置OnPoolDestroy方法是否被调用的标志
/// </summary>
public bool OnPoolDestroyCalled { get; set; } public bool OnPoolDestroyCalled { get; set; }
/// <summary>
/// 对象被获取时的回调方法
/// </summary>
public void OnAcquire() public void OnAcquire()
{ {
OnAcquireCalled = true; OnAcquireCalled = true;
} }
/// <summary>
/// 对象被释放时的回调方法
/// </summary>
public void OnRelease() public void OnRelease()
{ {
OnReleaseCalled = true; OnReleaseCalled = true;
} }
/// <summary>
/// 对象被销毁时的回调方法
/// </summary>
public void OnPoolDestroy() public void OnPoolDestroy()
{ {
OnPoolDestroyCalled = true; OnPoolDestroyCalled = true;

View File

@ -3,15 +3,24 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.property; namespace GFramework.Core.Tests.property;
/// <summary>
/// BindableProperty类的单元测试
/// </summary>
[TestFixture] [TestFixture]
public class BindablePropertyTests public class BindablePropertyTests
{ {
/// <summary>
/// 测试清理方法,在每个测试方法执行后重置比较器
/// </summary>
[TearDown] [TearDown]
public void TearDown() public void TearDown()
{ {
BindableProperty<string>.Comparer = (a, b) => a?.Equals(b) ?? b == null; BindableProperty<string>.Comparer = (a, b) => a?.Equals(b) ?? b == null;
} }
/// <summary>
/// 测试获取值时应返回默认值
/// </summary>
[Test] [Test]
public void Value_Get_Should_Return_Default_Value() public void Value_Get_Should_Return_Default_Value()
{ {
@ -20,6 +29,9 @@ public class BindablePropertyTests
Assert.That(property.Value, Is.EqualTo(5)); Assert.That(property.Value, Is.EqualTo(5));
} }
/// <summary>
/// 测试设置值时应触发事件
/// </summary>
[Test] [Test]
public void Value_Set_Should_Trigger_Event() public void Value_Set_Should_Trigger_Event()
{ {
@ -33,6 +45,9 @@ public class BindablePropertyTests
Assert.That(receivedValue, Is.EqualTo(42)); Assert.That(receivedValue, Is.EqualTo(42));
} }
/// <summary>
/// 测试设置相同值时不触发事件
/// </summary>
[Test] [Test]
public void Value_Set_To_Same_Value_Should_Not_Trigger_Event() public void Value_Set_To_Same_Value_Should_Not_Trigger_Event()
{ {
@ -46,6 +61,9 @@ public class BindablePropertyTests
Assert.That(count, Is.EqualTo(0)); Assert.That(count, Is.EqualTo(0));
} }
/// <summary>
/// 测试取消注册应移除处理器
/// </summary>
[Test] [Test]
public void UnRegister_Should_Remove_Handler() public void UnRegister_Should_Remove_Handler()
{ {
@ -63,6 +81,9 @@ public class BindablePropertyTests
Assert.That(count, Is.EqualTo(1)); Assert.That(count, Is.EqualTo(1));
} }
/// <summary>
/// 测试带初始值注册应立即调用处理器
/// </summary>
[Test] [Test]
public void RegisterWithInitValue_Should_Call_Handler_Immediately() public void RegisterWithInitValue_Should_Call_Handler_Immediately()
{ {
@ -74,6 +95,9 @@ public class BindablePropertyTests
Assert.That(receivedValue, Is.EqualTo(5)); Assert.That(receivedValue, Is.EqualTo(5));
} }
/// <summary>
/// 测试无事件设置值不应触发事件
/// </summary>
[Test] [Test]
public void SetValueWithoutEvent_Should_Not_Trigger_Event() public void SetValueWithoutEvent_Should_Not_Trigger_Event()
{ {
@ -88,12 +112,16 @@ public class BindablePropertyTests
Assert.That(property.Value, Is.EqualTo(42)); Assert.That(property.Value, Is.EqualTo(42));
} }
/// <summary>
/// 测试使用自定义比较器
/// </summary>
[Test] [Test]
public void WithComparer_Should_Use_Custom_Comparer() public void WithComparer_Should_Use_Custom_Comparer()
{ {
var comparerWasCalled = false; var comparerWasCalled = false;
var comparisonResult = false; var comparisonResult = false;
// 设置自定义比较器
BindableProperty<string>.Comparer = (a, b) => BindableProperty<string>.Comparer = (a, b) =>
{ {
comparerWasCalled = true; comparerWasCalled = true;
@ -112,6 +140,9 @@ public class BindablePropertyTests
Assert.That(count, Is.EqualTo(0), "不应该触发事件"); Assert.That(count, Is.EqualTo(0), "不应该触发事件");
} }
/// <summary>
/// 测试多个处理器都应被调用
/// </summary>
[Test] [Test]
public void Multiple_Handlers_Should_All_Be_Called() public void Multiple_Handlers_Should_All_Be_Called()
{ {
@ -128,6 +159,9 @@ public class BindablePropertyTests
Assert.That(count2, Is.EqualTo(1)); Assert.That(count2, Is.EqualTo(1));
} }
/// <summary>
/// 测试注册应返回IUnRegister接口
/// </summary>
[Test] [Test]
public void Register_Should_Return_IUnRegister() public void Register_Should_Return_IUnRegister()
{ {
@ -137,6 +171,9 @@ public class BindablePropertyTests
Assert.That(unRegister, Is.Not.Null); Assert.That(unRegister, Is.Not.Null);
} }
/// <summary>
/// 测试ToString应返回值的字符串表示
/// </summary>
[Test] [Test]
public void ToString_Should_Return_Value_As_String() public void ToString_Should_Return_Value_As_String()
{ {

View File

@ -4,9 +4,15 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.query; namespace GFramework.Core.Tests.query;
/// <summary>
/// 查询总线测试类用于测试QueryBus的功能和异常处理
/// </summary>
[TestFixture] [TestFixture]
public class QueryBusTests public class QueryBusTests
{ {
/// <summary>
/// 测试设置方法,在每个测试方法执行前初始化查询总线实例
/// </summary>
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -15,6 +21,10 @@ public class QueryBusTests
private QueryBus _queryBus = null!; private QueryBus _queryBus = null!;
/// <summary>
/// 测试Send方法是否能正确返回查询结果
/// 验证当传入有效查询对象时,能够得到预期的计算结果
/// </summary>
[Test] [Test]
public void Send_Should_Return_Query_Result() public void Send_Should_Return_Query_Result()
{ {
@ -26,12 +36,20 @@ public class QueryBusTests
Assert.That(result, Is.EqualTo(20)); Assert.That(result, Is.EqualTo(20));
} }
/// <summary>
/// 测试Send方法在传入空查询对象时是否会抛出ArgumentNullException异常
/// 验证参数验证功能的正确性
/// </summary>
[Test] [Test]
public void Send_WithNullQuery_Should_ThrowArgumentNullException() public void Send_WithNullQuery_Should_ThrowArgumentNullException()
{ {
Assert.Throws<ArgumentNullException>(() => _queryBus.Send<int>(null!)); Assert.Throws<ArgumentNullException>(() => _queryBus.Send<int>(null!));
} }
/// <summary>
/// 测试Send方法是否能正确返回字符串类型的查询结果
/// 验证不同返回类型的支持情况
/// </summary>
[Test] [Test]
public void Send_WithStringResult_Should_Return_String() public void Send_WithStringResult_Should_Return_String()
{ {
@ -44,29 +62,62 @@ public class QueryBusTests
} }
} }
/// <summary>
/// 测试用查询输入类实现IQueryInput接口
/// 用于传递查询所需的参数信息
/// </summary>
public sealed class TestQueryInput : IQueryInput public sealed class TestQueryInput : IQueryInput
{ {
/// <summary>
/// 获取或设置查询值
/// </summary>
public int Value { get; init; } public int Value { get; init; }
} }
/// <summary>
/// 整数类型测试查询类继承自AbstractQuery
/// 实现具体的查询逻辑并返回整数结果
/// </summary>
public sealed class TestQuery : AbstractQuery<TestQueryInput, int> public sealed class TestQuery : AbstractQuery<TestQueryInput, int>
{ {
/// <summary>
/// 初始化TestQuery的新实例
/// </summary>
/// <param name="input">查询输入参数</param>
public TestQuery(TestQueryInput input) : base(input) public TestQuery(TestQueryInput input) : base(input)
{ {
} }
/// <summary>
/// 执行查询操作的具体实现
/// </summary>
/// <param name="input">查询输入参数</param>
/// <returns>查询结果将输入值乘以2</returns>
protected override int OnDo(TestQueryInput input) protected override int OnDo(TestQueryInput input)
{ {
return input.Value * 2; return input.Value * 2;
} }
} }
/// <summary>
/// 字符串类型测试查询类继承自AbstractQuery
/// 实现具体的查询逻辑并返回字符串结果
/// </summary>
public sealed class TestStringQuery : AbstractQuery<TestQueryInput, string> public sealed class TestStringQuery : AbstractQuery<TestQueryInput, string>
{ {
/// <summary>
/// 初始化TestStringQuery的新实例
/// </summary>
/// <param name="input">查询输入参数</param>
public TestStringQuery(TestQueryInput input) : base(input) public TestStringQuery(TestQueryInput input) : base(input)
{ {
} }
/// <summary>
/// 执行查询操作的具体实现
/// </summary>
/// <param name="input">查询输入参数</param>
/// <returns>格式化的字符串结果</returns>
protected override string OnDo(TestQueryInput input) protected override string OnDo(TestQueryInput input)
{ {
return $"Result: {input.Value * 2}"; return $"Result: {input.Value * 2}";

View File

@ -7,9 +7,17 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.rule; namespace GFramework.Core.Tests.rule;
/// <summary>
/// 测试 ContextAware 功能的单元测试类
/// 验证上下文感知对象的设置、获取和回调功能
/// </summary>
[TestFixture] [TestFixture]
public class ContextAwareTests public class ContextAwareTests
{ {
/// <summary>
/// 在每个测试方法执行前进行初始化设置
/// 创建测试用的 ContextAware 对象和模拟上下文,并绑定到游戏上下文中
/// </summary>
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -18,6 +26,10 @@ public class ContextAwareTests
GameContext.Bind(typeof(TestArchitectureContext), _mockContext); GameContext.Bind(typeof(TestArchitectureContext), _mockContext);
} }
/// <summary>
/// 在每个测试方法执行后进行清理工作
/// 从游戏上下文中解绑测试用的架构上下文类型
/// </summary>
[TearDown] [TearDown]
public void TearDown() public void TearDown()
{ {
@ -27,6 +39,10 @@ public class ContextAwareTests
private TestContextAware _contextAware = null!; private TestContextAware _contextAware = null!;
private TestArchitectureContext _mockContext = null!; private TestArchitectureContext _mockContext = null!;
/// <summary>
/// 测试 SetContext 方法是否正确设置上下文属性
/// 验证通过 IContextAware 接口设置上下文后,内部的 PublicContext 属性能够正确返回设置的上下文
/// </summary>
[Test] [Test]
public void SetContext_Should_Set_Context_Property() public void SetContext_Should_Set_Context_Property()
{ {
@ -36,6 +52,10 @@ public class ContextAwareTests
Assert.That(_contextAware.PublicContext, Is.SameAs(_mockContext)); Assert.That(_contextAware.PublicContext, Is.SameAs(_mockContext));
} }
/// <summary>
/// 测试 SetContext 方法是否正确调用 OnContextReady 回调方法
/// 验证设置上下文后OnContextReady 方法被正确触发
/// </summary>
[Test] [Test]
public void SetContext_Should_Call_OnContextReady() public void SetContext_Should_Call_OnContextReady()
{ {
@ -45,6 +65,10 @@ public class ContextAwareTests
Assert.That(_contextAware.OnContextReadyCalled, Is.True); Assert.That(_contextAware.OnContextReadyCalled, Is.True);
} }
/// <summary>
/// 测试 GetContext 方法是否返回已设置的上下文
/// 验证通过 IContextAware 接口设置上下文后GetContext 方法能正确返回相同的上下文实例
/// </summary>
[Test] [Test]
public void GetContext_Should_Return_Set_Context() public void GetContext_Should_Return_Set_Context()
{ {
@ -56,6 +80,11 @@ public class ContextAwareTests
Assert.That(result, Is.SameAs(_mockContext)); Assert.That(result, Is.SameAs(_mockContext));
} }
/// <summary>
/// 测试 GetContext 方法在未设置上下文时的行为
/// 验证当内部 Context 为 null 时GetContext 方法不会抛出异常
/// 此时应返回第一个架构上下文(在测试环境中验证不抛出异常即可)
/// </summary>
[Test] [Test]
public void GetContext_Should_Return_FirstArchitectureContext_When_Not_Set() public void GetContext_Should_Return_FirstArchitectureContext_When_Not_Set()
{ {
@ -72,11 +101,26 @@ public class ContextAwareTests
} }
} }
/// <summary>
/// 用于测试的 ContextAware 实现类
/// 继承自 ContextAwareBase提供公共访问的上下文属性和回调状态跟踪
/// </summary>
public class TestContextAware : ContextAwareBase public class TestContextAware : ContextAwareBase
{ {
/// <summary>
/// 获取内部上下文的公共访问属性
/// </summary>
public IArchitectureContext? PublicContext => Context; public IArchitectureContext? PublicContext => Context;
/// <summary>
/// 跟踪 OnContextReady 方法是否被调用的状态
/// </summary>
public bool OnContextReadyCalled { get; private set; } public bool OnContextReadyCalled { get; private set; }
/// <summary>
/// 重写上下文就绪回调方法
/// 设置 OnContextReadyCalled 标志为 true用于测试验证
/// </summary>
protected override void OnContextReady() protected override void OnContextReady()
{ {
OnContextReadyCalled = true; OnContextReadyCalled = true;

View File

@ -1,4 +1,3 @@
using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.enums; using GFramework.Core.Abstractions.enums;
using GFramework.Core.Abstractions.state; using GFramework.Core.Abstractions.state;
using GFramework.Core.Abstractions.system; using GFramework.Core.Abstractions.system;
@ -13,13 +12,26 @@ using NUnit.Framework;
namespace GFramework.Core.Tests.state; namespace GFramework.Core.Tests.state;
/// <summary>
/// ContextAwareStateMachine类的单元测试
/// 测试内容包括:
/// - 作为ISystem的集成测试
/// - Init方法 - 初始化上下文感知状态
/// - Init方法 - 设置Context属性
/// - Destroy方法 - 清理状态
/// - OnArchitecturePhase方法 - 接收架构阶段
/// - 上下文感知状态初始化
/// - 状态变更事件发送
/// - SetContext方法
/// - GetContext方法
/// - ISystem接口实现验证
/// - 与EventBus的集成测试
/// - 多状态注册和切换
/// - 状态机生命周期完整性
/// </summary>
[TestFixture] [TestFixture]
public class ContextAwareStateMachineTests public class ContextAwareStateMachineTests
{ {
private TestContextAwareStateMachineV5? _stateMachine;
private ArchitectureContext? _context;
private EventBus? _eventBus;
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -35,12 +47,22 @@ public class ContextAwareStateMachineTests
_stateMachine.SetContext(_context); _stateMachine.SetContext(_context);
} }
private TestContextAwareStateMachineV5? _stateMachine;
private ArchitectureContext? _context;
private EventBus? _eventBus;
/// <summary>
/// 测试ContextAwareStateMachine实现ISystem接口
/// </summary>
[Test] [Test]
public void ContextAwareStateMachine_Should_Implement_ISystem_Interface() public void ContextAwareStateMachine_Should_Implement_ISystem_Interface()
{ {
Assert.That(_stateMachine, Is.InstanceOf<ISystem>()); Assert.That(_stateMachine, Is.InstanceOf<ISystem>());
} }
/// <summary>
/// 测试SetContext设置Context属性
/// </summary>
[Test] [Test]
public void SetContext_Should_Set_Context_Property() public void SetContext_Should_Set_Context_Property()
{ {
@ -50,6 +72,9 @@ public class ContextAwareStateMachineTests
Assert.That(context, Is.SameAs(_context)); Assert.That(context, Is.SameAs(_context));
} }
/// <summary>
/// 测试GetContext返回Context属性
/// </summary>
[Test] [Test]
public void GetContext_Should_Return_Context_Property() public void GetContext_Should_Return_Context_Property()
{ {
@ -60,6 +85,9 @@ public class ContextAwareStateMachineTests
Assert.That(context, Is.SameAs(_context)); Assert.That(context, Is.SameAs(_context));
} }
/// <summary>
/// 测试Init方法为所有ContextAware状态设置Context
/// </summary>
[Test] [Test]
public void Init_Should_SetContext_On_All_ContextAware_States() public void Init_Should_SetContext_On_All_ContextAware_States()
{ {
@ -78,6 +106,9 @@ public class ContextAwareStateMachineTests
Assert.That(state2.GetContext(), Is.SameAs(_context)); Assert.That(state2.GetContext(), Is.SameAs(_context));
} }
/// <summary>
/// 测试Init方法不为非ContextAware状态设置Context
/// </summary>
[Test] [Test]
public void Init_Should_Not_SetContext_On_NonContextAware_States() public void Init_Should_Not_SetContext_On_NonContextAware_States()
{ {
@ -87,12 +118,18 @@ public class ContextAwareStateMachineTests
_stateMachine.Init(); _stateMachine.Init();
} }
/// <summary>
/// 测试Destroy方法不抛出异常
/// </summary>
[Test] [Test]
public void Destroy_Should_Not_Throw_Exception() public void Destroy_Should_Not_Throw_Exception()
{ {
Assert.That(() => _stateMachine!.Destroy(), Throws.Nothing); Assert.That(() => _stateMachine!.Destroy(), Throws.Nothing);
} }
/// <summary>
/// 测试OnArchitecturePhase方法不抛出异常
/// </summary>
[Test] [Test]
public void OnArchitecturePhase_Should_Not_Throw_Exception() public void OnArchitecturePhase_Should_Not_Throw_Exception()
{ {
@ -100,9 +137,14 @@ public class ContextAwareStateMachineTests
Throws.Nothing); Throws.Nothing);
} }
/// <summary>
/// 测试ChangeTo发送StateChangedEvent事件
/// 验证当状态机切换到新状态时会正确触发StateChangedEvent事件并且事件中的旧状态为null首次切换
/// </summary>
[Test] [Test]
public void ChangeTo_Should_Send_StateChangedEvent() public void ChangeTo_Should_Send_StateChangedEvent()
{ {
// 订阅StateChangedEvent事件以验证事件是否被正确发送
bool eventReceived = false; bool eventReceived = false;
StateChangedEvent? receivedEvent = null; StateChangedEvent? receivedEvent = null;
@ -126,9 +168,15 @@ public class ContextAwareStateMachineTests
Assert.That(receivedEvent.NewState, Is.InstanceOf<TestStateV5>()); Assert.That(receivedEvent.NewState, Is.InstanceOf<TestStateV5>());
} }
/// <summary>
/// 测试ChangeTo发送StateChangedEvent事件包含旧状态
/// 验证当状态机从一个状态切换到另一个状态时会正确触发StateChangedEvent事件
/// 并且事件中包含正确的旧状态和新状态信息
/// </summary>
[Test] [Test]
public void ChangeTo_Should_Send_StateChangedEvent_With_OldState() public void ChangeTo_Should_Send_StateChangedEvent_With_OldState()
{ {
// 订阅StateChangedEvent事件以验证事件是否被正确发送
bool eventReceived = false; bool eventReceived = false;
StateChangedEvent? receivedEvent = null; StateChangedEvent? receivedEvent = null;
@ -153,6 +201,10 @@ public class ContextAwareStateMachineTests
Assert.That(receivedEvent.NewState, Is.InstanceOf<TestStateV5>()); Assert.That(receivedEvent.NewState, Is.InstanceOf<TestStateV5>());
} }
/// <summary>
/// 测试CanChangeTo方法对于已注册状态的工作情况
/// 验证当状态已注册到状态机中时CanChangeTo方法应返回true
/// </summary>
[Test] [Test]
public void CanChangeTo_Should_Work_With_Registered_States() public void CanChangeTo_Should_Work_With_Registered_States()
{ {
@ -164,6 +216,10 @@ public class ContextAwareStateMachineTests
Assert.That(canChange, Is.True); Assert.That(canChange, Is.True);
} }
/// <summary>
/// 测试可以注册多个状态
/// 验证状态机能够成功注册多个不同的状态实例,并且能够切换到这些已注册的状态
/// </summary>
[Test] [Test]
public void Multiple_States_Should_Be_Registered() public void Multiple_States_Should_Be_Registered()
{ {
@ -179,6 +235,10 @@ public class ContextAwareStateMachineTests
Assert.That(canChange, Is.True); Assert.That(canChange, Is.True);
} }
/// <summary>
/// 测试状态机生命周期完整
/// </summary>
[Test] [Test]
public void StateMachine_Lifecycle_Should_Be_Complete() public void StateMachine_Lifecycle_Should_Be_Complete()
{ {
@ -200,43 +260,91 @@ public class ContextAwareStateMachineTests
#region Test Classes #region Test Classes
/// <summary>
/// 测试用的ContextAwareStateMachine派生类用于访问内部状态字典
/// </summary>
public class TestContextAwareStateMachineV5 : ContextAwareStateMachine public class TestContextAwareStateMachineV5 : ContextAwareStateMachine
{ {
/// <summary>
/// 获取状态机内部的状态字典
/// </summary>
/// <returns>类型到状态实例的映射字典</returns>
public Dictionary<Type, IState> GetStates() => States; public Dictionary<Type, IState> GetStates() => States;
} }
/// <summary>
/// 测试用的上下文感知状态基类实现
/// </summary>
public class TestContextAwareStateV5 : ContextAwareStateBase public class TestContextAwareStateV5 : ContextAwareStateBase
{ {
/// <summary>
/// 进入状态时调用
/// </summary>
/// <param name="previous">前一个状态</param>
public override void OnEnter(IState? previous) public override void OnEnter(IState? previous)
{ {
} }
/// <summary>
/// 退出状态时调用
/// </summary>
/// <param name="next">下一个状态</param>
public override void OnExit(IState? next) public override void OnExit(IState? next)
{ {
} }
} }
/// <summary>
/// 第二个测试用的上下文感知状态基类实现
/// </summary>
public class TestContextAwareStateV5_2 : ContextAwareStateBase public class TestContextAwareStateV5_2 : ContextAwareStateBase
{ {
/// <summary>
/// 进入状态时调用
/// </summary>
/// <param name="previous">前一个状态</param>
public override void OnEnter(IState? previous) public override void OnEnter(IState? previous)
{ {
} }
/// <summary>
/// 退出状态时调用
/// </summary>
/// <param name="next">下一个状态</param>
public override void OnExit(IState? next) public override void OnExit(IState? next)
{ {
} }
} }
/// <summary>
/// 测试用的普通状态实现
/// </summary>
public class TestStateV5 : IState public class TestStateV5 : IState
{ {
/// <summary>
/// 状态标识符
/// </summary>
public int Id { get; set; } public int Id { get; set; }
/// <summary>
/// 检查是否可以转换到指定状态
/// </summary>
/// <param name="next">目标状态</param>
/// <returns>始终返回true表示允许转换</returns>
public bool CanTransitionTo(IState next) => true; public bool CanTransitionTo(IState next) => true;
/// <summary>
/// 进入状态时调用
/// </summary>
/// <param name="previous">前一个状态</param>
public void OnEnter(IState? previous) public void OnEnter(IState? previous)
{ {
} }
/// <summary>
/// 退出状态时调用
/// </summary>
/// <param name="next">下一个状态</param>
public void OnExit(IState? next) public void OnExit(IState? next)
{ {
} }

View File

@ -1,12 +1,19 @@
using System.Reflection;
using GFramework.Core.Abstractions.state; using GFramework.Core.Abstractions.state;
using GFramework.Core.state; using GFramework.Core.state;
using NUnit.Framework; using NUnit.Framework;
namespace GFramework.Core.Tests.state; namespace GFramework.Core.Tests.state;
/// <summary>
/// 测试状态机功能的单元测试类
/// </summary>
[TestFixture] [TestFixture]
public class StateMachineTests public class StateMachineTests
{ {
/// <summary>
/// 在每个测试方法执行前初始化状态机实例
/// </summary>
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -15,12 +22,18 @@ public class StateMachineTests
private StateMachine _stateMachine = null!; private StateMachine _stateMachine = null!;
/// <summary>
/// 验证当没有活动状态时当前状态应为null
/// </summary>
[Test] [Test]
public void Current_Should_BeNull_When_NoState_Active() public void Current_Should_BeNull_When_NoState_Active()
{ {
Assert.That(_stateMachine.Current, Is.Null); Assert.That(_stateMachine.Current, Is.Null);
} }
/// <summary>
/// 验证注册状态后,状态会被添加到状态字典中
/// </summary>
[Test] [Test]
public void Register_Should_AddState_To_StatesDictionary() public void Register_Should_AddState_To_StatesDictionary()
{ {
@ -30,6 +43,9 @@ public class StateMachineTests
Assert.That(_stateMachine.ContainsState<TestStateV2>(), Is.True); Assert.That(_stateMachine.ContainsState<TestStateV2>(), Is.True);
} }
/// <summary>
/// 验证ChangeTo方法能够正确设置当前状态
/// </summary>
[Test] [Test]
public void ChangeTo_Should_SetCurrentState() public void ChangeTo_Should_SetCurrentState()
{ {
@ -40,6 +56,9 @@ public class StateMachineTests
Assert.That(_stateMachine.Current, Is.SameAs(state)); Assert.That(_stateMachine.Current, Is.SameAs(state));
} }
/// <summary>
/// 验证ChangeTo方法会调用OnEnter回调
/// </summary>
[Test] [Test]
public void ChangeTo_Should_Invoke_OnEnter() public void ChangeTo_Should_Invoke_OnEnter()
{ {
@ -51,6 +70,9 @@ public class StateMachineTests
Assert.That(state.EnterFrom, Is.Null); Assert.That(state.EnterFrom, Is.Null);
} }
/// <summary>
/// 验证当存在当前状态时切换到新状态会调用原状态的OnExit回调
/// </summary>
[Test] [Test]
public void ChangeTo_When_CurrentStateExists_Should_Invoke_OnExit() public void ChangeTo_When_CurrentStateExists_Should_Invoke_OnExit()
{ {
@ -66,6 +88,9 @@ public class StateMachineTests
Assert.That(state1.ExitTo, Is.SameAs(state2)); Assert.That(state1.ExitTo, Is.SameAs(state2));
} }
/// <summary>
/// 验证当存在当前状态时切换到新状态会调用新状态的OnEnter回调
/// </summary>
[Test] [Test]
public void ChangeTo_When_CurrentStateExists_Should_Invoke_OnEnter() public void ChangeTo_When_CurrentStateExists_Should_Invoke_OnEnter()
{ {
@ -81,6 +106,9 @@ public class StateMachineTests
Assert.That(state2.EnterFrom, Is.SameAs(state1)); Assert.That(state2.EnterFrom, Is.SameAs(state1));
} }
/// <summary>
/// 验证切换到相同状态时不应调用回调方法
/// </summary>
[Test] [Test]
public void ChangeTo_ToSameState_Should_NotInvoke_Callbacks() public void ChangeTo_ToSameState_Should_NotInvoke_Callbacks()
{ {
@ -97,12 +125,18 @@ public class StateMachineTests
Assert.That(state.ExitCallCount, Is.EqualTo(exitCount)); Assert.That(state.ExitCallCount, Is.EqualTo(exitCount));
} }
/// <summary>
/// 验证切换到未注册状态时应抛出InvalidOperationException异常
/// </summary>
[Test] [Test]
public void ChangeTo_ToUnregisteredState_Should_ThrowInvalidOperationException() public void ChangeTo_ToUnregisteredState_Should_ThrowInvalidOperationException()
{ {
Assert.Throws<InvalidOperationException>(() => _stateMachine.ChangeTo<TestStateV2>()); Assert.Throws<InvalidOperationException>(() => _stateMachine.ChangeTo<TestStateV2>());
} }
/// <summary>
/// 验证当状态未注册时CanChangeTo方法应返回false
/// </summary>
[Test] [Test]
public void CanChangeTo_WhenStateNotRegistered_Should_ReturnFalse() public void CanChangeTo_WhenStateNotRegistered_Should_ReturnFalse()
{ {
@ -110,6 +144,9 @@ public class StateMachineTests
Assert.That(result, Is.False); Assert.That(result, Is.False);
} }
/// <summary>
/// 验证当状态已注册时CanChangeTo方法应返回true
/// </summary>
[Test] [Test]
public void CanChangeTo_WhenStateRegistered_Should_ReturnTrue() public void CanChangeTo_WhenStateRegistered_Should_ReturnTrue()
{ {
@ -120,6 +157,9 @@ public class StateMachineTests
Assert.That(result, Is.True); Assert.That(result, Is.True);
} }
/// <summary>
/// 验证当当前状态拒绝转换时CanChangeTo方法应返回false
/// </summary>
[Test] [Test]
public void CanChangeTo_WhenCurrentStateDeniesTransition_Should_ReturnFalse() public void CanChangeTo_WhenCurrentStateDeniesTransition_Should_ReturnFalse()
{ {
@ -133,6 +173,9 @@ public class StateMachineTests
Assert.That(result, Is.False); Assert.That(result, Is.False);
} }
/// <summary>
/// 验证当当前状态拒绝转换时不应发生状态变化
/// </summary>
[Test] [Test]
public void ChangeTo_WhenCurrentStateDeniesTransition_Should_NotChange() public void ChangeTo_WhenCurrentStateDeniesTransition_Should_NotChange()
{ {
@ -150,6 +193,9 @@ public class StateMachineTests
Assert.That(state2.EnterCalled, Is.False); Assert.That(state2.EnterCalled, Is.False);
} }
/// <summary>
/// 验证注销状态后应从字典中移除该状态
/// </summary>
[Test] [Test]
public void Unregister_Should_RemoveState_FromDictionary() public void Unregister_Should_RemoveState_FromDictionary()
{ {
@ -160,6 +206,9 @@ public class StateMachineTests
Assert.That(_stateMachine.ContainsState<TestStateV2>(), Is.False); Assert.That(_stateMachine.ContainsState<TestStateV2>(), Is.False);
} }
/// <summary>
/// 验证当活动状态被注销时应调用OnExit并清除当前状态
/// </summary>
[Test] [Test]
public void Unregister_WhenStateIsActive_Should_Invoke_OnExit_AndClearCurrent() public void Unregister_WhenStateIsActive_Should_Invoke_OnExit_AndClearCurrent()
{ {
@ -173,6 +222,9 @@ public class StateMachineTests
Assert.That(_stateMachine.Current, Is.Null); Assert.That(_stateMachine.Current, Is.Null);
} }
/// <summary>
/// 验证当非活动状态被注销时不应调用OnExit
/// </summary>
[Test] [Test]
public void Unregister_WhenStateNotActive_Should_Not_Invoke_OnExit() public void Unregister_WhenStateNotActive_Should_Not_Invoke_OnExit()
{ {
@ -188,6 +240,9 @@ public class StateMachineTests
Assert.That(_stateMachine.Current, Is.SameAs(state1)); Assert.That(_stateMachine.Current, Is.SameAs(state1));
} }
/// <summary>
/// 验证多次状态转换应正确调用回调方法
/// </summary>
[Test] [Test]
public void MultipleStateChanges_Should_Invoke_Callbacks_Correctly() public void MultipleStateChanges_Should_Invoke_Callbacks_Correctly()
{ {
@ -210,6 +265,9 @@ public class StateMachineTests
Assert.That(state3.ExitCalled, Is.False); Assert.That(state3.ExitCalled, Is.False);
} }
/// <summary>
/// 验证ChangeTo方法应遵循CanTransitionTo逻辑
/// </summary>
[Test] [Test]
public void ChangeTo_Should_Respect_CanTransitionTo_Logic() public void ChangeTo_Should_Respect_CanTransitionTo_Logic()
{ {
@ -229,6 +287,9 @@ public class StateMachineTests
} }
} }
/// <summary>
/// 测试状态类V2版本实现IState接口用于测试
/// </summary>
public sealed class TestStateV2 : IState public sealed class TestStateV2 : IState
{ {
public bool AllowTransition { get; set; } = true; public bool AllowTransition { get; set; } = true;
@ -239,6 +300,10 @@ public sealed class TestStateV2 : IState
public IState? EnterFrom { get; private set; } public IState? EnterFrom { get; private set; }
public IState? ExitTo { get; private set; } public IState? ExitTo { get; private set; }
/// <summary>
/// 进入状态时的回调方法
/// </summary>
/// <param name="from">从哪个状态进入</param>
public void OnEnter(IState? from) public void OnEnter(IState? from)
{ {
EnterCalled = true; EnterCalled = true;
@ -246,6 +311,10 @@ public sealed class TestStateV2 : IState
EnterFrom = from; EnterFrom = from;
} }
/// <summary>
/// 离开状态时的回调方法
/// </summary>
/// <param name="to">离开到哪个状态</param>
public void OnExit(IState? to) public void OnExit(IState? to)
{ {
ExitCalled = true; ExitCalled = true;
@ -253,12 +322,20 @@ public sealed class TestStateV2 : IState
ExitTo = to; ExitTo = to;
} }
/// <summary>
/// 判断是否可以转换到目标状态
/// </summary>
/// <param name="target">目标状态</param>
/// <returns>是否允许转换</returns>
public bool CanTransitionTo(IState target) public bool CanTransitionTo(IState target)
{ {
return AllowTransition; return AllowTransition;
} }
} }
/// <summary>
/// 测试状态类V3版本实现IState接口用于测试
/// </summary>
public sealed class TestStateV3 : IState public sealed class TestStateV3 : IState
{ {
public bool EnterCalled { get; private set; } public bool EnterCalled { get; private set; }
@ -268,6 +345,10 @@ public sealed class TestStateV3 : IState
public IState? EnterFrom { get; private set; } public IState? EnterFrom { get; private set; }
public IState? ExitTo { get; private set; } public IState? ExitTo { get; private set; }
/// <summary>
/// 进入状态时的回调方法
/// </summary>
/// <param name="from">从哪个状态进入</param>
public void OnEnter(IState? from) public void OnEnter(IState? from)
{ {
EnterCalled = true; EnterCalled = true;
@ -275,6 +356,10 @@ public sealed class TestStateV3 : IState
EnterFrom = from; EnterFrom = from;
} }
/// <summary>
/// 离开状态时的回调方法
/// </summary>
/// <param name="to">离开到哪个状态</param>
public void OnExit(IState? to) public void OnExit(IState? to)
{ {
ExitCalled = true; ExitCalled = true;
@ -282,12 +367,20 @@ public sealed class TestStateV3 : IState
ExitTo = to; ExitTo = to;
} }
/// <summary>
/// 判断是否可以转换到目标状态
/// </summary>
/// <param name="target">目标状态</param>
/// <returns>是否允许转换</returns>
public bool CanTransitionTo(IState target) public bool CanTransitionTo(IState target)
{ {
return true; return true;
} }
} }
/// <summary>
/// 测试状态类V4版本实现IState接口用于测试
/// </summary>
public sealed class TestStateV4 : IState public sealed class TestStateV4 : IState
{ {
public bool EnterCalled { get; private set; } public bool EnterCalled { get; private set; }
@ -297,6 +390,10 @@ public sealed class TestStateV4 : IState
public IState? EnterFrom { get; private set; } public IState? EnterFrom { get; private set; }
public IState? ExitTo { get; private set; } public IState? ExitTo { get; private set; }
/// <summary>
/// 进入状态时的回调方法
/// </summary>
/// <param name="from">从哪个状态进入</param>
public void OnEnter(IState? from) public void OnEnter(IState? from)
{ {
EnterCalled = true; EnterCalled = true;
@ -304,6 +401,10 @@ public sealed class TestStateV4 : IState
EnterFrom = from; EnterFrom = from;
} }
/// <summary>
/// 离开状态时的回调方法
/// </summary>
/// <param name="to">离开到哪个状态</param>
public void OnExit(IState? to) public void OnExit(IState? to)
{ {
ExitCalled = true; ExitCalled = true;
@ -311,18 +412,32 @@ public sealed class TestStateV4 : IState
ExitTo = to; ExitTo = to;
} }
/// <summary>
/// 判断是否可以转换到目标状态
/// </summary>
/// <param name="target">目标状态</param>
/// <returns>是否允许转换</returns>
public bool CanTransitionTo(IState target) public bool CanTransitionTo(IState target)
{ {
return true; return true;
} }
} }
/// <summary>
/// 状态机扩展方法类
/// </summary>
public static class StateMachineExtensions 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 public static bool ContainsState<T>(this StateMachine stateMachine) where T : IState
{ {
return stateMachine.GetType().GetField("States", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)? return stateMachine.GetType().GetField("States", BindingFlags.NonPublic | BindingFlags.Instance)?
.GetValue(stateMachine) is System.Collections.Generic.Dictionary<System.Type, IState> states && .GetValue(stateMachine) is Dictionary<Type, IState> states &&
states.ContainsKey(typeof(T)); states.ContainsKey(typeof(T));
} }
} }

View File

@ -1,12 +1,17 @@
using GFramework.Core.Abstractions.state; using GFramework.Core.Abstractions.state;
using GFramework.Core.state;
using NUnit.Framework; using NUnit.Framework;
namespace GFramework.Core.Tests.state; namespace GFramework.Core.Tests.state;
/// <summary>
/// 测试状态模式实现的功能和行为
/// </summary>
[TestFixture] [TestFixture]
public class StateTests public class StateTests
{ {
/// <summary>
/// 验证状态类是否正确实现了IState接口
/// </summary>
[Test] [Test]
public void State_Should_Implement_IState_Interface() public void State_Should_Implement_IState_Interface()
{ {
@ -15,6 +20,9 @@ public class StateTests
Assert.That(state is IState); Assert.That(state is IState);
} }
/// <summary>
/// 验证进入状态时OnEnter方法被正确调用并记录来源状态
/// </summary>
[Test] [Test]
public void OnEnter_Should_BeCalled_When_State_Enters() public void OnEnter_Should_BeCalled_When_State_Enters()
{ {
@ -27,6 +35,9 @@ public class StateTests
Assert.That(state.EnterFrom, Is.SameAs(otherState)); Assert.That(state.EnterFrom, Is.SameAs(otherState));
} }
/// <summary>
/// 验证当传入null作为来源状态时的处理情况
/// </summary>
[Test] [Test]
public void OnEnter_WithNull_Should_Set_EnterFrom_ToNull() public void OnEnter_WithNull_Should_Set_EnterFrom_ToNull()
{ {
@ -38,6 +49,9 @@ public class StateTests
Assert.That(state.EnterFrom, Is.Null); Assert.That(state.EnterFrom, Is.Null);
} }
/// <summary>
/// 验证退出状态时OnExit方法被正确调用并记录目标状态
/// </summary>
[Test] [Test]
public void OnExit_Should_BeCalled_When_State_Exits() public void OnExit_Should_BeCalled_When_State_Exits()
{ {
@ -50,6 +64,9 @@ public class StateTests
Assert.That(state.ExitTo, Is.SameAs(otherState)); Assert.That(state.ExitTo, Is.SameAs(otherState));
} }
/// <summary>
/// 验证当传入null作为目标状态时的处理情况
/// </summary>
[Test] [Test]
public void OnExit_WithNull_Should_Set_ExitTo_ToNull() public void OnExit_WithNull_Should_Set_ExitTo_ToNull()
{ {
@ -61,6 +78,9 @@ public class StateTests
Assert.That(state.ExitTo, Is.Null); Assert.That(state.ExitTo, Is.Null);
} }
/// <summary>
/// 验证允许转换时CanTransitionTo方法返回true
/// </summary>
[Test] [Test]
public void CanTransitionTo_WithAllowTrue_Should_ReturnTrue() public void CanTransitionTo_WithAllowTrue_Should_ReturnTrue()
{ {
@ -72,6 +92,9 @@ public class StateTests
Assert.That(result, Is.True); Assert.That(result, Is.True);
} }
/// <summary>
/// 验证不允许转换时CanTransitionTo方法返回false
/// </summary>
[Test] [Test]
public void CanTransitionTo_WithAllowFalse_Should_ReturnFalse() public void CanTransitionTo_WithAllowFalse_Should_ReturnFalse()
{ {
@ -83,6 +106,9 @@ public class StateTests
Assert.That(result, Is.False); Assert.That(result, Is.False);
} }
/// <summary>
/// 验证CanTransitionTo方法正确接收目标状态参数
/// </summary>
[Test] [Test]
public void CanTransitionTo_Should_Receive_TargetState() public void CanTransitionTo_Should_Receive_TargetState()
{ {
@ -96,6 +122,9 @@ public class StateTests
Assert.That(receivedTarget, Is.SameAs(target)); Assert.That(receivedTarget, Is.SameAs(target));
} }
/// <summary>
/// 验证具有复杂转换规则的状态类功能
/// </summary>
[Test] [Test]
public void State_WithComplexTransitionRules_Should_Work() public void State_WithComplexTransitionRules_Should_Work()
{ {
@ -107,6 +136,9 @@ public class StateTests
Assert.That(state1.CanTransitionTo(state3), Is.False); Assert.That(state1.CanTransitionTo(state3), Is.False);
} }
/// <summary>
/// 验证多个状态之间的协作功能
/// </summary>
[Test] [Test]
public void MultipleStates_Should_WorkTogether() public void MultipleStates_Should_WorkTogether()
{ {
@ -126,6 +158,9 @@ public class StateTests
Assert.That(state3.EnterFrom, Is.SameAs(state2)); Assert.That(state3.EnterFrom, Is.SameAs(state2));
} }
/// <summary>
/// 验证状态对多次转换的跟踪能力
/// </summary>
[Test] [Test]
public void State_Should_Track_MultipleTransitions() public void State_Should_Track_MultipleTransitions()
{ {
@ -141,6 +176,9 @@ public class StateTests
Assert.That(state.ExitCallCount, Is.EqualTo(2)); Assert.That(state.ExitCallCount, Is.EqualTo(2));
} }
/// <summary>
/// 验证相同类型状态间的转换处理
/// </summary>
[Test] [Test]
public void State_Should_Handle_SameState_Transition() public void State_Should_Handle_SameState_Transition()
{ {
@ -158,27 +196,66 @@ public class StateTests
} }
} }
/// <summary>
/// 具体状态实现类V2版本用于测试状态的基本功能
/// </summary>
public sealed class ConcreteStateV2 : IState public sealed class ConcreteStateV2 : IState
{ {
/// <summary>
/// 获取或设置是否允许转换
/// </summary>
public bool AllowTransitions { get; set; } = true; public bool AllowTransitions { get; set; } = true;
/// <summary>
/// 获取进入状态是否被调用的标志
/// </summary>
public bool EnterCalled { get; private set; } public bool EnterCalled { get; private set; }
/// <summary>
/// 获取退出状态是否被调用的标志
/// </summary>
public bool ExitCalled { get; private set; } public bool ExitCalled { get; private set; }
/// <summary>
/// 获取进入此状态的来源状态
/// </summary>
public IState? EnterFrom { get; private set; } public IState? EnterFrom { get; private set; }
/// <summary>
/// 获取从此状态退出的目标状态
/// </summary>
public IState? ExitTo { get; private set; } public IState? ExitTo { get; private set; }
/// <summary>
/// 获取或设置转换到目标状态时执行的动作
/// </summary>
public Action<IState>? CanTransitionToAction { get; set; } public Action<IState>? CanTransitionToAction { get; set; }
/// <summary>
/// 进入当前状态时调用的方法
/// </summary>
/// <param name="from">从哪个状态进入</param>
public void OnEnter(IState? from) public void OnEnter(IState? from)
{ {
EnterCalled = true; EnterCalled = true;
EnterFrom = from; EnterFrom = from;
} }
/// <summary>
/// 退出当前状态时调用的方法
/// </summary>
/// <param name="to">退出到哪个状态</param>
public void OnExit(IState? to) public void OnExit(IState? to)
{ {
ExitCalled = true; ExitCalled = true;
ExitTo = to; ExitTo = to;
} }
/// <summary>
/// 判断是否可以转换到目标状态
/// </summary>
/// <param name="target">目标状态</param>
/// <returns>如果可以转换则返回true否则返回false</returns>
public bool CanTransitionTo(IState target) public bool CanTransitionTo(IState target)
{ {
CanTransitionToAction?.Invoke(target); CanTransitionToAction?.Invoke(target);
@ -186,101 +263,229 @@ public sealed class ConcreteStateV2 : IState
} }
} }
/// <summary>
/// 具体状态实现类V3版本用于测试状态的基本功能
/// </summary>
public sealed class ConcreteStateV3 : IState public sealed class ConcreteStateV3 : IState
{ {
/// <summary>
/// 获取进入状态是否被调用的标志
/// </summary>
public bool EnterCalled { get; private set; } public bool EnterCalled { get; private set; }
/// <summary>
/// 获取退出状态是否被调用的标志
/// </summary>
public bool ExitCalled { get; private set; } public bool ExitCalled { get; private set; }
/// <summary>
/// 获取进入此状态的来源状态
/// </summary>
public IState? EnterFrom { get; private set; } public IState? EnterFrom { get; private set; }
/// <summary>
/// 获取从此状态退出的目标状态
/// </summary>
public IState? ExitTo { get; private set; } public IState? ExitTo { get; private set; }
/// <summary>
/// 进入当前状态时调用的方法
/// </summary>
/// <param name="from">从哪个状态进入</param>
public void OnEnter(IState? from) public void OnEnter(IState? from)
{ {
EnterCalled = true; EnterCalled = true;
EnterFrom = from; EnterFrom = from;
} }
/// <summary>
/// 退出当前状态时调用的方法
/// </summary>
/// <param name="to">退出到哪个状态</param>
public void OnExit(IState? to) public void OnExit(IState? to)
{ {
ExitCalled = true; ExitCalled = true;
ExitTo = to; ExitTo = to;
} }
/// <summary>
/// 判断是否可以转换到目标状态
/// </summary>
/// <param name="target">目标状态</param>
/// <returns>如果可以转换则返回true否则返回false</returns>
public bool CanTransitionTo(IState target) public bool CanTransitionTo(IState target)
{ {
return true; return true;
} }
} }
/// <summary>
/// 具体状态实现类V4版本用于测试状态的基本功能
/// </summary>
public sealed class ConcreteStateV4 : IState public sealed class ConcreteStateV4 : IState
{ {
/// <summary>
/// 获取进入状态是否被调用的标志
/// </summary>
public bool EnterCalled { get; private set; } public bool EnterCalled { get; private set; }
/// <summary>
/// 获取退出状态是否被调用的标志
/// </summary>
public bool ExitCalled { get; private set; } public bool ExitCalled { get; private set; }
/// <summary>
/// 获取进入此状态的来源状态
/// </summary>
public IState? EnterFrom { get; private set; } public IState? EnterFrom { get; private set; }
/// <summary>
/// 获取从此状态退出的目标状态
/// </summary>
public IState? ExitTo { get; private set; } public IState? ExitTo { get; private set; }
/// <summary>
/// 进入当前状态时调用的方法
/// </summary>
/// <param name="from">从哪个状态进入</param>
public void OnEnter(IState? from) public void OnEnter(IState? from)
{ {
EnterCalled = true; EnterCalled = true;
EnterFrom = from; EnterFrom = from;
} }
/// <summary>
/// 退出当前状态时调用的方法
/// </summary>
/// <param name="to">退出到哪个状态</param>
public void OnExit(IState? to) public void OnExit(IState? to)
{ {
ExitCalled = true; ExitCalled = true;
ExitTo = to; ExitTo = to;
} }
/// <summary>
/// 判断是否可以转换到目标状态
/// </summary>
/// <param name="target">目标状态</param>
/// <returns>如果可以转换则返回true否则返回false</returns>
public bool CanTransitionTo(IState target) public bool CanTransitionTo(IState target)
{ {
return true; return true;
} }
} }
/// <summary>
/// 条件状态实现类V2版本支持基于类型的条件转换规则
/// </summary>
public sealed class ConditionalStateV2 : IState public sealed class ConditionalStateV2 : IState
{ {
/// <summary>
/// 获取或设置允许转换到的状态类型数组
/// </summary>
public Type[] AllowedTransitions { get; set; } = Array.Empty<Type>(); public Type[] AllowedTransitions { get; set; } = Array.Empty<Type>();
/// <summary>
/// 获取进入状态是否被调用的标志
/// </summary>
public bool EnterCalled { get; private set; } public bool EnterCalled { get; private set; }
/// <summary>
/// 获取退出状态是否被调用的标志
/// </summary>
public bool ExitCalled { get; private set; } public bool ExitCalled { get; private set; }
/// <summary>
/// 获取进入此状态的来源状态
/// </summary>
public IState? EnterFrom { get; private set; } public IState? EnterFrom { get; private set; }
/// <summary>
/// 获取从此状态退出的目标状态
/// </summary>
public IState? ExitTo { get; private set; } public IState? ExitTo { get; private set; }
/// <summary>
/// 进入当前状态时调用的方法
/// </summary>
/// <param name="from">从哪个状态进入</param>
public void OnEnter(IState? from) public void OnEnter(IState? from)
{ {
EnterCalled = true; EnterCalled = true;
EnterFrom = from; EnterFrom = from;
} }
/// <summary>
/// 退出当前状态时调用的方法
/// </summary>
/// <param name="to">退出到哪个状态</param>
public void OnExit(IState? to) public void OnExit(IState? to)
{ {
ExitCalled = true; ExitCalled = true;
ExitTo = to; ExitTo = to;
} }
/// <summary>
/// 判断是否可以转换到目标状态
/// </summary>
/// <param name="target">目标状态</param>
/// <returns>如果目标状态类型在允许列表中则返回true否则返回false</returns>
public bool CanTransitionTo(IState target) public bool CanTransitionTo(IState target)
{ {
return AllowedTransitions.Contains(target.GetType()); return AllowedTransitions.Contains(target.GetType());
} }
} }
/// <summary>
/// 跟踪状态实现类V2版本用于跟踪状态转换次数
/// </summary>
public sealed class TrackingStateV2 : IState public sealed class TrackingStateV2 : IState
{ {
/// <summary>
/// 获取进入状态被调用的次数
/// </summary>
public int EnterCallCount { get; private set; } public int EnterCallCount { get; private set; }
/// <summary>
/// 获取退出状态被调用的次数
/// </summary>
public int ExitCallCount { get; private set; } public int ExitCallCount { get; private set; }
/// <summary>
/// 获取进入此状态的来源状态
/// </summary>
public IState? EnterFrom { get; private set; } public IState? EnterFrom { get; private set; }
/// <summary>
/// 获取从此状态退出的目标状态
/// </summary>
public IState? ExitTo { get; private set; } public IState? ExitTo { get; private set; }
/// <summary>
/// 进入当前状态时调用的方法
/// </summary>
/// <param name="from">从哪个状态进入</param>
public void OnEnter(IState? from) public void OnEnter(IState? from)
{ {
EnterCallCount++; EnterCallCount++;
EnterFrom = from; EnterFrom = from;
} }
/// <summary>
/// 退出当前状态时调用的方法
/// </summary>
/// <param name="to">退出到哪个状态</param>
public void OnExit(IState? to) public void OnExit(IState? to)
{ {
ExitCallCount++; ExitCallCount++;
ExitTo = to; ExitTo = to;
} }
/// <summary>
/// 判断是否可以转换到目标状态
/// </summary>
/// <param name="target">目标状态</param>
/// <returns>总是返回true</returns>
public bool CanTransitionTo(IState target) public bool CanTransitionTo(IState target)
{ {
return true; return true;