mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
test(architecture): 添加异步架构测试并重构测试基类
- 创建 AsyncTestArchitecture 类用于异步测试 - 添加 AsyncTestSystem 实现异步初始化系统 - 创建 ArchitectureTestsBase 基类统一同步异步测试逻辑 - 实现 AsyncArchitectureTests 异步架构测试用例 - 将同步测试重构为继承自 ArchitectureTestsBase - 移除重复的测试方法实现 - 重命名模型初始化状态属性为 Initialized
This commit is contained in:
parent
67b0e83da4
commit
78da01878b
55
GFramework.Core.Tests/architecture/AsyncTestArchitecture.cs
Normal file
55
GFramework.Core.Tests/architecture/AsyncTestArchitecture.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using GFramework.Core.Abstractions.enums;
|
||||
using GFramework.Core.architecture;
|
||||
using GFramework.Core.events;
|
||||
using GFramework.Core.Tests.model;
|
||||
using GFramework.Core.Tests.system;
|
||||
|
||||
namespace GFramework.Core.Tests.architecture;
|
||||
|
||||
/// <summary>
|
||||
/// 异步测试架构,用于测试异步模型和系统的初始化
|
||||
/// </summary>
|
||||
public class AsyncTestArchitecture : Architecture
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化完成事件是否触发
|
||||
/// </summary>
|
||||
public bool ReadyEventFired { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Init 方法是否调用
|
||||
/// </summary>
|
||||
public bool InitCalled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 阶段进入记录
|
||||
/// </summary>
|
||||
public List<ArchitecturePhase> PhaseHistory { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 异步初始化架构
|
||||
/// </summary>
|
||||
protected override void Init()
|
||||
{
|
||||
InitCalled = true;
|
||||
|
||||
// 注册模型
|
||||
RegisterModel(new AsyncTestModel());
|
||||
|
||||
// 注册系统
|
||||
RegisterSystem(new AsyncTestSystem());
|
||||
|
||||
// 订阅 Ready 事件
|
||||
Context.RegisterEvent<ArchitectureEvents.ArchitectureLifecycleReadyEvent>(_ => { ReadyEventFired = true; });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 进入阶段时记录
|
||||
/// </summary>
|
||||
/// <param name="next"></param>
|
||||
protected override void EnterPhase(ArchitecturePhase next)
|
||||
{
|
||||
base.EnterPhase(next);
|
||||
PhaseHistory.Add(next);
|
||||
}
|
||||
}
|
||||
@ -14,7 +14,7 @@ public sealed class AsyncTestModel : IModel, IAsyncInitializable
|
||||
/// <summary>
|
||||
/// 获取模型是否已初始化的标志
|
||||
/// </summary>
|
||||
public bool Inited { get; private set; }
|
||||
public bool Initialized { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 异步初始化方法,模拟异步初始化过程
|
||||
@ -23,7 +23,7 @@ public sealed class AsyncTestModel : IModel, IAsyncInitializable
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await Task.Delay(10);
|
||||
Inited = true;
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -14,14 +14,14 @@ public sealed class TestModel : IModel
|
||||
/// <summary>
|
||||
/// 获取模型是否已初始化的状态
|
||||
/// </summary>
|
||||
public bool Inited { get; private set; }
|
||||
public bool Initialized { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始化模型
|
||||
/// </summary>
|
||||
public void Init()
|
||||
{
|
||||
Inited = true;
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
public void SetContext(IArchitectureContext context)
|
||||
|
||||
36
GFramework.Core.Tests/system/AsyncTestSystem.cs
Normal file
36
GFramework.Core.Tests/system/AsyncTestSystem.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using GFramework.Core.Abstractions.architecture;
|
||||
using GFramework.Core.Abstractions.enums;
|
||||
using GFramework.Core.Abstractions.system;
|
||||
|
||||
namespace GFramework.Core.Tests.system;
|
||||
|
||||
/// <summary>
|
||||
/// 异步测试系统,实现 ISystem 和 IAsyncInitializable
|
||||
/// </summary>
|
||||
public sealed class AsyncTestSystem : ISystem, IAsyncInitializable
|
||||
{
|
||||
private IArchitectureContext _context = null!;
|
||||
public bool Initialized { get; private set; }
|
||||
public bool DestroyCalled { get; private set; }
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await Task.Delay(10);
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
public void SetContext(IArchitectureContext context) => _context = context;
|
||||
public IArchitectureContext GetContext() => _context;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// 同步 Init 不应该被调用
|
||||
throw new InvalidOperationException("Sync Init should not be called");
|
||||
}
|
||||
|
||||
public void Destroy() => DestroyCalled = true;
|
||||
|
||||
public void OnArchitecturePhase(ArchitecturePhase phase)
|
||||
{
|
||||
}
|
||||
}
|
||||
141
GFramework.Core.Tests/tests/ArchitectureTestsBase.cs
Normal file
141
GFramework.Core.Tests/tests/ArchitectureTestsBase.cs
Normal file
@ -0,0 +1,141 @@
|
||||
using System.Reflection;
|
||||
using GFramework.Core.Abstractions.enums;
|
||||
using GFramework.Core.architecture;
|
||||
using GFramework.Core.Tests.architecture;
|
||||
using GFramework.Core.Tests.model;
|
||||
using GFramework.Core.Tests.system;
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework.Legacy;
|
||||
|
||||
namespace GFramework.Core.Tests.tests;
|
||||
|
||||
/// <summary>
|
||||
/// 架构测试基类,封装同步/异步共通测试逻辑
|
||||
/// </summary>
|
||||
/// <typeparam name="TArchitecture">架构类型,必须继承自Architecture</typeparam>
|
||||
public abstract class ArchitectureTestsBase<TArchitecture> where TArchitecture : Architecture
|
||||
{
|
||||
protected TArchitecture? Architecture;
|
||||
|
||||
/// <summary>
|
||||
/// 子类必须实现创建具体架构实例
|
||||
/// </summary>
|
||||
/// <returns>创建的架构实例</returns>
|
||||
protected abstract TArchitecture CreateArchitecture();
|
||||
|
||||
/// <summary>
|
||||
/// 子类必须实现初始化架构(同步或异步)
|
||||
/// </summary>
|
||||
/// <returns>异步初始化任务</returns>
|
||||
protected abstract Task InitializeArchitecture();
|
||||
|
||||
/// <summary>
|
||||
/// 测试设置方法,在每个测试开始前执行
|
||||
/// 清理游戏上下文并创建架构实例
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
GameContext.Clear();
|
||||
Architecture = CreateArchitecture();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试清理方法,在每个测试结束后执行
|
||||
/// 销毁架构实例并清理游戏上下文
|
||||
/// </summary>
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
try
|
||||
{
|
||||
Architecture?.Destroy();
|
||||
}
|
||||
finally
|
||||
{
|
||||
GameContext.Clear();
|
||||
Architecture = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证架构阶段顺序
|
||||
/// </summary>
|
||||
/// <returns>异步测试任务</returns>
|
||||
[Test]
|
||||
public async Task Architecture_Should_Enter_Phases_In_Correct_Order()
|
||||
{
|
||||
await InitializeArchitecture();
|
||||
|
||||
// 通过反射获取架构的阶段历史记录
|
||||
var phasesProperty = typeof(TArchitecture)
|
||||
.GetProperty("PhaseHistory", BindingFlags.Instance | BindingFlags.Public);
|
||||
|
||||
var phases = (List<ArchitecturePhase>)phasesProperty!.GetValue(Architecture)!;
|
||||
|
||||
CollectionAssert.AreEqual(
|
||||
new[]
|
||||
{
|
||||
ArchitecturePhase.BeforeModelInit,
|
||||
ArchitecturePhase.AfterModelInit,
|
||||
ArchitecturePhase.BeforeSystemInit,
|
||||
ArchitecturePhase.AfterSystemInit,
|
||||
ArchitecturePhase.Ready
|
||||
},
|
||||
phases
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证 Ready 后不能注册组件
|
||||
/// </summary>
|
||||
/// <returns>异步测试任务</returns>
|
||||
[Test]
|
||||
public async Task Registering_Components_AfterReady_Should_Throw()
|
||||
{
|
||||
await InitializeArchitecture();
|
||||
|
||||
// 根据架构类型验证注册组件时抛出异常
|
||||
if (Architecture is SyncTestArchitecture syncArch)
|
||||
{
|
||||
Assert.Throws<InvalidOperationException>(() => syncArch.RegisterModel(new TestModel()));
|
||||
Assert.Throws<InvalidOperationException>(() => syncArch.RegisterSystem(new TestSystem()));
|
||||
}
|
||||
else if (Architecture is AsyncTestArchitecture asyncArch)
|
||||
{
|
||||
Assert.Throws<InvalidOperationException>(() => asyncArch.RegisterModel(new AsyncTestModel()));
|
||||
Assert.Throws<InvalidOperationException>(() => asyncArch.RegisterSystem(new AsyncTestSystem()));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证销毁功能
|
||||
/// </summary>
|
||||
/// <returns>异步测试任务</returns>
|
||||
[Test]
|
||||
public async Task Architecture_Destroy_Should_Destroy_All_Systems_And_Enter_Destroyed()
|
||||
{
|
||||
await InitializeArchitecture();
|
||||
|
||||
Architecture!.Destroy();
|
||||
|
||||
// 验证系统是否被正确销毁
|
||||
if (Architecture is SyncTestArchitecture syncArch)
|
||||
{
|
||||
var system = syncArch.Context.GetSystem<TestSystem>();
|
||||
Assert.That(system!.DestroyCalled, Is.True);
|
||||
}
|
||||
else if (Architecture is AsyncTestArchitecture asyncArch)
|
||||
{
|
||||
var system = asyncArch.Context.GetSystem<AsyncTestSystem>();
|
||||
Assert.That(system!.DestroyCalled, Is.True);
|
||||
}
|
||||
|
||||
// 通过反射验证当前阶段为销毁状态
|
||||
var phaseProperty = typeof(TArchitecture)
|
||||
.GetProperty("CurrentPhase", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
var phase = (ArchitecturePhase)phaseProperty!.GetValue(Architecture)!;
|
||||
Assert.That(phase, Is.EqualTo(ArchitecturePhase.Destroyed));
|
||||
}
|
||||
}
|
||||
30
GFramework.Core.Tests/tests/AsyncArchitectureTests.cs
Normal file
30
GFramework.Core.Tests/tests/AsyncArchitectureTests.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using GFramework.Core.Tests.architecture;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GFramework.Core.Tests.tests;
|
||||
|
||||
/// <summary>
|
||||
/// 异步架构测试类,用于测试异步架构的相关功能
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 该测试类使用非并行执行模式,确保测试的隔离性
|
||||
/// </remarks>
|
||||
[TestFixture]
|
||||
[NonParallelizable]
|
||||
public class AsyncArchitectureTests : ArchitectureTestsBase<AsyncTestArchitecture>
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建异步测试架构实例
|
||||
/// </summary>
|
||||
/// <returns>AsyncTestArchitecture实例</returns>
|
||||
protected override AsyncTestArchitecture CreateArchitecture() => new();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化架构的异步方法
|
||||
/// </summary>
|
||||
/// <returns>表示异步操作的Task</returns>
|
||||
protected override async Task InitializeArchitecture()
|
||||
{
|
||||
await Architecture!.InitializeAsync();
|
||||
}
|
||||
}
|
||||
@ -5,46 +5,35 @@ using GFramework.Core.Tests.architecture;
|
||||
using GFramework.Core.Tests.model;
|
||||
using GFramework.Core.Tests.system;
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework.Legacy;
|
||||
|
||||
namespace GFramework.Core.Tests.tests;
|
||||
|
||||
/// <summary>
|
||||
/// 同步架构测试类,用于测试同步架构的初始化、生命周期和组件注册等功能
|
||||
/// 同步架构测试类,用于测试同步架构的功能和行为
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 该测试类使用非并行执行模式,确保测试的隔离性和可靠性
|
||||
/// </remarks>
|
||||
[TestFixture]
|
||||
[NonParallelizable]
|
||||
public class SyncArchitectureTests
|
||||
public class SyncArchitectureTests : ArchitectureTestsBase<SyncTestArchitecture>
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试初始化方法,清理游戏上下文并创建同步测试架构实例
|
||||
/// 创建同步测试架构实例
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
GameContext.Clear();
|
||||
_architecture = new SyncTestArchitecture();
|
||||
}
|
||||
/// <returns>SyncTestArchitecture实例</returns>
|
||||
protected override SyncTestArchitecture CreateArchitecture() => new SyncTestArchitecture();
|
||||
|
||||
/// <summary>
|
||||
/// 测试清理方法,销毁架构实例并清理游戏上下文
|
||||
/// 初始化架构异步方法
|
||||
/// </summary>
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
/// <returns>表示异步操作的Task</returns>
|
||||
protected override Task InitializeArchitecture()
|
||||
{
|
||||
try
|
||||
{
|
||||
_architecture?.Destroy();
|
||||
}
|
||||
finally
|
||||
{
|
||||
GameContext.Clear();
|
||||
_architecture = null;
|
||||
}
|
||||
Architecture!.Initialize();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private SyncTestArchitecture? _architecture;
|
||||
|
||||
/// <summary>
|
||||
/// 测试架构是否正确初始化所有组件
|
||||
/// 验证初始化调用、运行时状态、架构阶段和模型系统注册
|
||||
@ -53,25 +42,25 @@ public class SyncArchitectureTests
|
||||
public void Architecture_Should_Initialize_All_Components_Correctly()
|
||||
{
|
||||
// Act
|
||||
_architecture!.Initialize();
|
||||
Architecture!.Initialize();
|
||||
|
||||
// Assert
|
||||
Assert.That(_architecture.InitCalled, Is.True);
|
||||
Assert.That(Architecture.InitCalled, Is.True);
|
||||
|
||||
Assert.That(_architecture.Runtime, Is.Not.Null);
|
||||
Assert.That(Architecture.Runtime, Is.Not.Null);
|
||||
|
||||
// 通过反射获取当前架构阶段
|
||||
var phaseProperty = typeof(Architecture)
|
||||
.GetProperty("CurrentPhase", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
var phase = (ArchitecturePhase)phaseProperty!.GetValue(_architecture)!;
|
||||
var phase = (ArchitecturePhase)phaseProperty!.GetValue(Architecture)!;
|
||||
Assert.That(phase, Is.EqualTo(ArchitecturePhase.Ready));
|
||||
|
||||
var context = _architecture.Context;
|
||||
var context = Architecture.Context;
|
||||
|
||||
var model = context.GetModel<TestModel>();
|
||||
Assert.That(model, Is.Not.Null);
|
||||
Assert.That(model!.Inited, Is.True);
|
||||
Assert.That(model!.Initialized, Is.True);
|
||||
|
||||
var system = context.GetSystem<TestSystem>();
|
||||
Assert.That(system, Is.Not.Null);
|
||||
@ -85,86 +74,20 @@ public class SyncArchitectureTests
|
||||
public void Architecture_Should_Register_Context_By_Type()
|
||||
{
|
||||
// Act
|
||||
_architecture!.Initialize();
|
||||
var ctx = GameContext.GetByType(_architecture!.GetType());
|
||||
Architecture!.Initialize();
|
||||
var ctx = GameContext.GetByType(Architecture!.GetType());
|
||||
|
||||
Assert.That(ctx, Is.Not.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试架构是否按正确顺序进入各个阶段
|
||||
/// 验证架构初始化过程中各阶段的执行顺序
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Architecture_Should_Enter_Phases_In_Correct_Order()
|
||||
{
|
||||
_architecture!.Initialize();
|
||||
|
||||
var phases = _architecture.PhaseHistory;
|
||||
|
||||
CollectionAssert.AreEqual(
|
||||
new[]
|
||||
{
|
||||
ArchitecturePhase.BeforeModelInit,
|
||||
ArchitecturePhase.AfterModelInit,
|
||||
ArchitecturePhase.BeforeSystemInit,
|
||||
ArchitecturePhase.AfterSystemInit,
|
||||
ArchitecturePhase.Ready
|
||||
},
|
||||
phases
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试在架构就绪后注册系统是否抛出异常(当不允许时)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void RegisterSystem_AfterReady_Should_Throw_When_NotAllowed()
|
||||
{
|
||||
_architecture!.Initialize();
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => { _architecture.RegisterSystem(new TestSystem()); });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试在架构就绪后注册模型是否抛出异常(当不允许时)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void RegisterModel_AfterReady_Should_Throw_When_NotAllowed()
|
||||
{
|
||||
_architecture!.Initialize();
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => { _architecture.RegisterModel(new TestModel()); });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试架构销毁功能,验证销毁后系统被正确销毁且架构进入销毁阶段
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Architecture_Destroy_Should_Destroy_All_Systems_And_Enter_Destroyed()
|
||||
{
|
||||
_architecture!.Initialize();
|
||||
_architecture.Destroy();
|
||||
|
||||
var system = _architecture.Context.GetSystem<TestSystem>();
|
||||
Assert.That(system!.DestroyCalled, Is.True);
|
||||
|
||||
// 通过反射获取当前架构阶段
|
||||
var phaseProperty = typeof(Architecture)
|
||||
.GetProperty("CurrentPhase", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
var phase = (ArchitecturePhase)phaseProperty!.GetValue(_architecture)!;
|
||||
Assert.That(phase, Is.EqualTo(ArchitecturePhase.Destroyed));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试当模型初始化失败时架构是否停止初始化
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Architecture_Should_Stop_Initialization_When_Model_Init_Fails()
|
||||
{
|
||||
_architecture!.RegisterModel(new FailingModel());
|
||||
Architecture!.RegisterModel(new FailingModel());
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => { _architecture!.Initialize(); });
|
||||
Assert.Throws<InvalidOperationException>(() => { Architecture!.Initialize(); });
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user