From ada0d3acbfd1277affd6c48e45de4402321e91e0 Mon Sep 17 00:00:00 2001
From: gewuyou <95328647+GeWuYou@users.noreply.github.com>
Date: Mon, 27 Apr 2026 18:47:34 +0800
Subject: [PATCH] =?UTF-8?q?test(state):=20=E6=8B=86=E5=88=86=20StateMachin?=
=?UTF-8?q?eTests=20=E7=8A=B6=E6=80=81=E6=B5=8B=E8=AF=95=E8=BE=85=E5=8A=A9?=
=?UTF-8?q?=E7=B1=BB=E5=9E=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 拆分 StateMachineTests 中的状态测试辅助类型到独立文件
- 补充提取后类型与扩展方法的 XML 文档说明
- 保持状态机测试行为不变并完成定向项目构建验证
---
.../State/StateMachineExtensions.cs | 24 ++
.../State/StateMachineTests.cs | 235 ------------------
GFramework.Core.Tests/State/TestAsyncState.cs | 116 +++++++++
GFramework.Core.Tests/State/TestStateV2.cs | 76 ++++++
GFramework.Core.Tests/State/TestStateV3.cs | 71 ++++++
GFramework.Core.Tests/State/TestStateV4.cs | 71 ++++++
6 files changed, 358 insertions(+), 235 deletions(-)
create mode 100644 GFramework.Core.Tests/State/StateMachineExtensions.cs
create mode 100644 GFramework.Core.Tests/State/TestAsyncState.cs
create mode 100644 GFramework.Core.Tests/State/TestStateV2.cs
create mode 100644 GFramework.Core.Tests/State/TestStateV3.cs
create mode 100644 GFramework.Core.Tests/State/TestStateV4.cs
diff --git a/GFramework.Core.Tests/State/StateMachineExtensions.cs b/GFramework.Core.Tests/State/StateMachineExtensions.cs
new file mode 100644
index 00000000..685471a9
--- /dev/null
+++ b/GFramework.Core.Tests/State/StateMachineExtensions.cs
@@ -0,0 +1,24 @@
+using System.Reflection;
+using GFramework.Core.Abstractions.State;
+using GFramework.Core.State;
+
+namespace GFramework.Core.Tests.State;
+
+///
+/// 为状态机测试提供仅限断言场景使用的反射辅助方法。
+///
+public static class StateMachineExtensions
+{
+ ///
+ /// 检查状态机内部缓存中是否已注册指定类型的状态。
+ ///
+ /// 要检查的状态类型。
+ /// 待检查的状态机实例。
+ /// 找到对应状态类型时返回 ,否则返回 。
+ public static bool ContainsState(this StateMachine stateMachine) where T : IState
+ {
+ return stateMachine.GetType().GetField("States", BindingFlags.NonPublic | BindingFlags.Instance)?
+ .GetValue(stateMachine) is Dictionary states &&
+ states.ContainsKey(typeof(T));
+ }
+}
diff --git a/GFramework.Core.Tests/State/StateMachineTests.cs b/GFramework.Core.Tests/State/StateMachineTests.cs
index 9edfb036..135e242d 100644
--- a/GFramework.Core.Tests/State/StateMachineTests.cs
+++ b/GFramework.Core.Tests/State/StateMachineTests.cs
@@ -1,4 +1,3 @@
-using System.Reflection;
using GFramework.Core.Abstractions.State;
using GFramework.Core.State;
using NUnit.Framework;
@@ -368,237 +367,3 @@ public class StateMachineTests
Assert.That(state3.ExitCalled, Is.False);
}
}
-
-///
-/// 测试状态类V2版本,实现IState接口用于测试
-///
-public sealed class TestStateV2 : IState
-{
- public bool AllowTransition { get; set; } = true;
- public bool EnterCalled { get; private set; }
- public bool ExitCalled { get; private set; }
- public int EnterCallCount { get; private set; }
- public int ExitCallCount { get; private set; }
- public IState? EnterFrom { get; private set; }
- public IState? ExitTo { get; private set; }
-
- ///
- /// 进入状态时的回调方法
- ///
- /// 从哪个状态进入
- public void OnEnter(IState? from)
- {
- EnterCalled = true;
- EnterCallCount++;
- EnterFrom = from;
- }
-
- ///
- /// 离开状态时的回调方法
- ///
- /// 离开到哪个状态
- public void OnExit(IState? to)
- {
- ExitCalled = true;
- ExitCallCount++;
- ExitTo = to;
- }
-
- ///
- /// 判断是否可以转换到目标状态
- ///
- /// 目标状态
- /// 是否允许转换
- public bool CanTransitionTo(IState target)
- {
- return AllowTransition;
- }
-}
-
-///
-/// 测试状态类V3版本,实现IState接口用于测试
-///
-public sealed class TestStateV3 : IState
-{
- public bool EnterCalled { get; private set; }
- public bool ExitCalled { get; private set; }
- public int EnterCallCount { get; private set; }
- public int ExitCallCount { get; private set; }
- public IState? EnterFrom { get; private set; }
- public IState? ExitTo { get; private set; }
-
- ///
- /// 进入状态时的回调方法
- ///
- /// 从哪个状态进入
- public void OnEnter(IState? from)
- {
- EnterCalled = true;
- EnterCallCount++;
- EnterFrom = from;
- }
-
- ///
- /// 离开状态时的回调方法
- ///
- /// 离开到哪个状态
- public void OnExit(IState? to)
- {
- ExitCalled = true;
- ExitCallCount++;
- ExitTo = to;
- }
-
- ///
- /// 判断是否可以转换到目标状态
- ///
- /// 目标状态
- /// 是否允许转换
- public bool CanTransitionTo(IState target)
- {
- return true;
- }
-}
-
-///
-/// 测试状态类V4版本,实现IState接口用于测试
-///
-public sealed class TestStateV4 : IState
-{
- public bool EnterCalled { get; private set; }
- public bool ExitCalled { get; private set; }
- public int EnterCallCount { get; private set; }
- public int ExitCallCount { get; private set; }
- public IState? EnterFrom { get; private set; }
- public IState? ExitTo { get; private set; }
-
- ///
- /// 进入状态时的回调方法
- ///
- /// 从哪个状态进入
- public void OnEnter(IState? from)
- {
- EnterCalled = true;
- EnterCallCount++;
- EnterFrom = from;
- }
-
- ///
- /// 离开状态时的回调方法
- ///
- /// 离开到哪个状态
- public void OnExit(IState? to)
- {
- ExitCalled = true;
- ExitCallCount++;
- ExitTo = to;
- }
-
- ///
- /// 判断是否可以转换到目标状态
- ///
- /// 目标状态
- /// 是否允许转换
- public bool CanTransitionTo(IState target)
- {
- return true;
- }
-}
-
-///
-/// 异步测试状态类,同时实现IState和IAsyncState接口用于测试异步状态功能
-///
-public sealed class TestAsyncState : IState, IAsyncState
-{
- public bool AllowTransition { get; set; } = true;
- public bool EnterCalled { get; private set; }
- public bool ExitCalled { get; private set; }
- public int EnterCallCount { get; private set; }
- public int ExitCallCount { get; private set; }
- public IState? EnterFrom { get; private set; }
- public IState? ExitTo { get; private set; }
- public int CanTransitionToCallCount { get; private set; }
-
- ///
- /// 异步进入状态时的回调方法
- ///
- /// 从哪个状态进入
- public async Task OnEnterAsync(IState? from)
- {
- await Task.Delay(1).ConfigureAwait(false);
- EnterCalled = true;
- EnterCallCount++;
- EnterFrom = from;
- }
-
- ///
- /// 异步离开状态时的回调方法
- ///
- /// 离开到哪个状态
- public async Task OnExitAsync(IState? to)
- {
- await Task.Delay(1).ConfigureAwait(false);
- ExitCalled = true;
- ExitCallCount++;
- ExitTo = to;
- }
-
- ///
- /// 异步判断是否可以转换到目标状态
- ///
- /// 目标状态
- /// 是否允许转换
- public async Task CanTransitionToAsync(IState target)
- {
- await Task.Delay(1).ConfigureAwait(false);
- CanTransitionToCallCount++;
- return AllowTransition;
- }
-
- ///
- /// 进入状态时的回调方法(同步版本,抛出异常表示不应被调用)
- ///
- /// 从哪个状态进入
- public void OnEnter(IState? from)
- {
- throw new InvalidOperationException("Sync OnEnter should not be called for async state");
- }
-
- ///
- /// 离开状态时的回调方法(同步版本,抛出异常表示不应被调用)
- ///
- /// 离开到哪个状态
- public void OnExit(IState? to)
- {
- throw new InvalidOperationException("Sync OnExit should not be called for async state");
- }
-
- ///
- /// 判断是否可以转换到目标状态(同步版本,抛出异常表示不应被调用)
- ///
- /// 目标状态
- /// 是否允许转换
- public bool CanTransitionTo(IState target)
- {
- throw new InvalidOperationException("Sync CanTransitionTo should not be called for async state");
- }
-}
-
-///
-/// 状态机扩展方法类
-///
-public static class StateMachineExtensions
-{
- ///
- /// 检查状态机是否包含指定类型的状态
- ///
- /// 要检查的状态类型
- /// 状态机实例
- /// 如果包含指定类型的状态则返回true,否则返回false
- public static bool ContainsState(this StateMachine stateMachine) where T : IState
- {
- return stateMachine.GetType().GetField("States", BindingFlags.NonPublic | BindingFlags.Instance)?
- .GetValue(stateMachine) is Dictionary states &&
- states.ContainsKey(typeof(T));
- }
-}
diff --git a/GFramework.Core.Tests/State/TestAsyncState.cs b/GFramework.Core.Tests/State/TestAsyncState.cs
new file mode 100644
index 00000000..af31b698
--- /dev/null
+++ b/GFramework.Core.Tests/State/TestAsyncState.cs
@@ -0,0 +1,116 @@
+using GFramework.Core.Abstractions.State;
+
+namespace GFramework.Core.Tests.State;
+
+///
+/// 为 提供异步生命周期路径的测试状态。
+///
+public sealed class TestAsyncState : IState, IAsyncState
+{
+ ///
+ /// 获取或设置是否允许向目标状态转移。
+ ///
+ public bool AllowTransition { get; set; } = true;
+
+ ///
+ /// 获取异步进入状态是否已被调用。
+ ///
+ public bool EnterCalled { get; private set; }
+
+ ///
+ /// 获取异步离开状态是否已被调用。
+ ///
+ public bool ExitCalled { get; private set; }
+
+ ///
+ /// 获取异步进入回调被调用的次数。
+ ///
+ public int EnterCallCount { get; private set; }
+
+ ///
+ /// 获取异步离开回调被调用的次数。
+ ///
+ public int ExitCallCount { get; private set; }
+
+ ///
+ /// 获取最近一次异步进入时的来源状态。
+ ///
+ public IState? EnterFrom { get; private set; }
+
+ ///
+ /// 获取最近一次异步离开时的目标状态。
+ ///
+ public IState? ExitTo { get; private set; }
+
+ ///
+ /// 获取异步转移检查被调用的次数。
+ ///
+ public int CanTransitionToCallCount { get; private set; }
+
+ ///
+ /// 异步记录进入状态的来源状态与调用次数。
+ ///
+ /// 触发进入的来源状态。
+ public async Task OnEnterAsync(IState? from)
+ {
+ await Task.Delay(1).ConfigureAwait(false);
+ EnterCalled = true;
+ EnterCallCount++;
+ EnterFrom = from;
+ }
+
+ ///
+ /// 异步记录离开状态的目标状态与调用次数。
+ ///
+ /// 即将切换到的目标状态。
+ public async Task OnExitAsync(IState? to)
+ {
+ await Task.Delay(1).ConfigureAwait(false);
+ ExitCalled = true;
+ ExitCallCount++;
+ ExitTo = to;
+ }
+
+ ///
+ /// 异步记录转移检查并返回当前是否允许切换。
+ ///
+ /// 目标状态。
+ /// 允许切换时返回 ,否则返回 。
+ public async Task CanTransitionToAsync(IState target)
+ {
+ await Task.Delay(1).ConfigureAwait(false);
+ CanTransitionToCallCount++;
+ return AllowTransition;
+ }
+
+ ///
+ /// 同步进入入口不应被异步状态机路径调用。
+ ///
+ /// 触发进入的来源状态。
+ /// 总是抛出,表示当前测试状态只允许异步入口。
+ public void OnEnter(IState? from)
+ {
+ throw new InvalidOperationException("Sync OnEnter should not be called for async state");
+ }
+
+ ///
+ /// 同步离开入口不应被异步状态机路径调用。
+ ///
+ /// 即将切换到的目标状态。
+ /// 总是抛出,表示当前测试状态只允许异步入口。
+ public void OnExit(IState? to)
+ {
+ throw new InvalidOperationException("Sync OnExit should not be called for async state");
+ }
+
+ ///
+ /// 同步转移检查入口不应被异步状态机路径调用。
+ ///
+ /// 目标状态。
+ /// 此方法不会正常返回。
+ /// 总是抛出,表示当前测试状态只允许异步入口。
+ public bool CanTransitionTo(IState target)
+ {
+ throw new InvalidOperationException("Sync CanTransitionTo should not be called for async state");
+ }
+}
diff --git a/GFramework.Core.Tests/State/TestStateV2.cs b/GFramework.Core.Tests/State/TestStateV2.cs
new file mode 100644
index 00000000..2d2f26d2
--- /dev/null
+++ b/GFramework.Core.Tests/State/TestStateV2.cs
@@ -0,0 +1,76 @@
+using GFramework.Core.Abstractions.State;
+
+namespace GFramework.Core.Tests.State;
+
+///
+/// 为 提供可配置转移结果的同步测试状态。
+///
+public sealed class TestStateV2 : IState
+{
+ ///
+ /// 获取或设置是否允许向目标状态转移。
+ ///
+ public bool AllowTransition { get; set; } = true;
+
+ ///
+ /// 获取进入状态是否已被调用。
+ ///
+ public bool EnterCalled { get; private set; }
+
+ ///
+ /// 获取离开状态是否已被调用。
+ ///
+ public bool ExitCalled { get; private set; }
+
+ ///
+ /// 获取进入回调被调用的次数。
+ ///
+ public int EnterCallCount { get; private set; }
+
+ ///
+ /// 获取离开回调被调用的次数。
+ ///
+ public int ExitCallCount { get; private set; }
+
+ ///
+ /// 获取最近一次进入时的来源状态。
+ ///
+ public IState? EnterFrom { get; private set; }
+
+ ///
+ /// 获取最近一次离开时的目标状态。
+ ///
+ public IState? ExitTo { get; private set; }
+
+ ///
+ /// 记录进入状态时的来源状态与调用次数。
+ ///
+ /// 触发进入的来源状态。
+ public void OnEnter(IState? from)
+ {
+ EnterCalled = true;
+ EnterCallCount++;
+ EnterFrom = from;
+ }
+
+ ///
+ /// 记录离开状态时的目标状态与调用次数。
+ ///
+ /// 即将切换到的目标状态。
+ public void OnExit(IState? to)
+ {
+ ExitCalled = true;
+ ExitCallCount++;
+ ExitTo = to;
+ }
+
+ ///
+ /// 根据 返回是否允许切换。
+ ///
+ /// 目标状态。
+ /// 允许切换时返回 ,否则返回 。
+ public bool CanTransitionTo(IState target)
+ {
+ return AllowTransition;
+ }
+}
diff --git a/GFramework.Core.Tests/State/TestStateV3.cs b/GFramework.Core.Tests/State/TestStateV3.cs
new file mode 100644
index 00000000..9bb05e4c
--- /dev/null
+++ b/GFramework.Core.Tests/State/TestStateV3.cs
@@ -0,0 +1,71 @@
+using GFramework.Core.Abstractions.State;
+
+namespace GFramework.Core.Tests.State;
+
+///
+/// 为 提供始终允许切换的同步测试状态。
+///
+public sealed class TestStateV3 : IState
+{
+ ///
+ /// 获取进入状态是否已被调用。
+ ///
+ public bool EnterCalled { get; private set; }
+
+ ///
+ /// 获取离开状态是否已被调用。
+ ///
+ public bool ExitCalled { get; private set; }
+
+ ///
+ /// 获取进入回调被调用的次数。
+ ///
+ public int EnterCallCount { get; private set; }
+
+ ///
+ /// 获取离开回调被调用的次数。
+ ///
+ public int ExitCallCount { get; private set; }
+
+ ///
+ /// 获取最近一次进入时的来源状态。
+ ///
+ public IState? EnterFrom { get; private set; }
+
+ ///
+ /// 获取最近一次离开时的目标状态。
+ ///
+ public IState? ExitTo { get; private set; }
+
+ ///
+ /// 记录进入状态时的来源状态与调用次数。
+ ///
+ /// 触发进入的来源状态。
+ public void OnEnter(IState? from)
+ {
+ EnterCalled = true;
+ EnterCallCount++;
+ EnterFrom = from;
+ }
+
+ ///
+ /// 记录离开状态时的目标状态与调用次数。
+ ///
+ /// 即将切换到的目标状态。
+ public void OnExit(IState? to)
+ {
+ ExitCalled = true;
+ ExitCallCount++;
+ ExitTo = to;
+ }
+
+ ///
+ /// 始终允许切换到目标状态。
+ ///
+ /// 目标状态。
+ /// 始终返回 。
+ public bool CanTransitionTo(IState target)
+ {
+ return true;
+ }
+}
diff --git a/GFramework.Core.Tests/State/TestStateV4.cs b/GFramework.Core.Tests/State/TestStateV4.cs
new file mode 100644
index 00000000..50788354
--- /dev/null
+++ b/GFramework.Core.Tests/State/TestStateV4.cs
@@ -0,0 +1,71 @@
+using GFramework.Core.Abstractions.State;
+
+namespace GFramework.Core.Tests.State;
+
+///
+/// 为 保留的附加同步测试状态实现。
+///
+public sealed class TestStateV4 : IState
+{
+ ///
+ /// 获取进入状态是否已被调用。
+ ///
+ public bool EnterCalled { get; private set; }
+
+ ///
+ /// 获取离开状态是否已被调用。
+ ///
+ public bool ExitCalled { get; private set; }
+
+ ///
+ /// 获取进入回调被调用的次数。
+ ///
+ public int EnterCallCount { get; private set; }
+
+ ///
+ /// 获取离开回调被调用的次数。
+ ///
+ public int ExitCallCount { get; private set; }
+
+ ///
+ /// 获取最近一次进入时的来源状态。
+ ///
+ public IState? EnterFrom { get; private set; }
+
+ ///
+ /// 获取最近一次离开时的目标状态。
+ ///
+ public IState? ExitTo { get; private set; }
+
+ ///
+ /// 记录进入状态时的来源状态与调用次数。
+ ///
+ /// 触发进入的来源状态。
+ public void OnEnter(IState? from)
+ {
+ EnterCalled = true;
+ EnterCallCount++;
+ EnterFrom = from;
+ }
+
+ ///
+ /// 记录离开状态时的目标状态与调用次数。
+ ///
+ /// 即将切换到的目标状态。
+ public void OnExit(IState? to)
+ {
+ ExitCalled = true;
+ ExitCallCount++;
+ ExitTo = to;
+ }
+
+ ///
+ /// 始终允许切换到目标状态。
+ ///
+ /// 目标状态。
+ /// 始终返回 。
+ public bool CanTransitionTo(IState target)
+ {
+ return true;
+ }
+}