Files
zeling_v2/Assets/Tests/EditMode/StatusEffectTests.cs

212 lines
7.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using NUnit.Framework;
using BaseGames.Combat.StatusEffects;
namespace BaseGames.Tests.EditMode
{
/// <summary>
/// StatusEffect 系统单元测试EditMode纯 C# 类,无需 MonoBehaviour
/// 覆盖:叠加规则、互斥规则、阻断规则、到期检测。
/// </summary>
[TestFixture]
public class StatusEffectTests
{
// ── 叠加规则 ─────────────────────────────────────────────────────────
[Test]
public void FireEffect_MaxStacks_IsOne()
{
var effect = new FireEffect();
Assert.AreEqual(1, effect.MaxStacks);
}
[Test]
public void PoisonEffect_MaxStacks_IsThree()
{
var effect = new PoisonEffect();
Assert.AreEqual(3, effect.MaxStacks);
}
[Test]
public void PoisonEffect_OnStack_IncreasesStackCount()
{
var effect = new PoisonEffect();
effect.OnStack();
Assert.AreEqual(2, effect.StackCount);
}
[Test]
public void PoisonEffect_OnStack_ClampsAtMaxStacks()
{
var effect = new PoisonEffect();
for (int i = 0; i < 10; i++) effect.OnStack();
Assert.AreEqual(effect.MaxStacks, effect.StackCount);
}
[Test]
public void StaggerEffect_MaxStacks_IsOne()
{
var effect = new StaggerEffect();
Assert.AreEqual(1, effect.MaxStacks);
}
// ── 互斥规则 ─────────────────────────────────────────────────────────
[Test]
public void FireEffect_MutualExclusions_ContainsFreeze()
{
var effect = new FireEffect();
Assert.Contains(StatusEffectType.Freeze, effect.MutualExclusions);
}
[Test]
public void PoisonEffect_MutualExclusions_IsEmpty()
{
var effect = new PoisonEffect();
Assert.IsEmpty(effect.MutualExclusions);
}
// ── 阻断规则 ─────────────────────────────────────────────────────────
[Test]
public void StaggerEffect_BlockedBy_ContainsStun()
{
var effect = new StaggerEffect();
Assert.Contains(StatusEffectType.Stun, effect.BlockedBy);
}
[Test]
public void FireEffect_BlockedBy_IsEmpty()
{
var effect = new FireEffect();
Assert.IsEmpty(effect.BlockedBy);
}
// ── 到期检测 ─────────────────────────────────────────────────────────
[Test]
public void StatusEffect_IsExpired_AfterDurationDepleted()
{
var effect = new StaggerEffect(0.5f);
effect.OnApply(null); // Owner 可为 null测试纯时间逻辑
effect.Update(0.3f);
Assert.IsFalse(effect.IsExpired);
effect.Update(0.3f); // 累计 0.6f > 0.5f
Assert.IsTrue(effect.IsExpired);
}
[Test]
public void FireEffect_OnStack_RefreshDuration()
{
var effectA = new FireEffect();
effectA.OnApply(null);
float initialDuration = effectA.Duration;
effectA.Update(1.0f); // 消耗部分时间
Assert.Less(effectA.Duration, initialDuration);
effectA.OnStack(); // 重叠施加,应刷新持续时间
Assert.AreEqual(initialDuration, effectA.Duration, 0.001f);
}
// ── 类型标识 ─────────────────────────────────────────────────────────
[Test]
public void FireEffect_EffectType_IsFire()
{
Assert.AreEqual(StatusEffectType.Fire, new FireEffect().EffectType);
}
[Test]
public void PoisonEffect_EffectType_IsPoison()
{
Assert.AreEqual(StatusEffectType.Poison, new PoisonEffect().EffectType);
}
[Test]
public void StaggerEffect_EffectType_IsStagger()
{
Assert.AreEqual(StatusEffectType.Stagger, new StaggerEffect().EffectType);
}
// ── 补充测试 ──────────────────────────────────────────────────────────
[Test]
public void StatusEffect_StackCount_InitialValueIsOne()
{
var effect = new FireEffect();
Assert.AreEqual(1, effect.StackCount, "新建 Effect 的初始 StackCount 应为 1");
}
[Test]
public void StatusEffect_Update_RemainingTime_Decreases()
{
var effect = new StaggerEffect(2.0f);
effect.OnApply(null);
float initialDuration = effect.Duration;
effect.Update(0.5f);
Assert.Less(effect.Duration, initialDuration, "Update 后剩余时间应减少");
Assert.IsFalse(effect.IsExpired, "0.5s Update 后 2.0s 效果不应过期");
}
[Test]
public void StatusEffect_Update_ExactExpiry()
{
var effect = new StaggerEffect(1.0f);
effect.OnApply(null);
effect.Update(1.0f); // 恰好耗尽
Assert.IsTrue(effect.IsExpired, "恰好耗尽 duration 后应 IsExpired == true");
}
[Test]
public void MultipleEffects_IndependentTimers()
{
var fire = new FireEffect();
var poison = new PoisonEffect();
fire.OnApply(null);
poison.OnApply(null);
float fireDuration = fire.Duration;
float poisonDuration = poison.Duration;
fire.Update(0.5f);
// poison 未调用 Update时间不应变化
Assert.AreEqual(poisonDuration, poison.Duration, 0.0001f,
"未 Update 的 Effect 持续时间不应减少");
Assert.Less(fire.Duration, fireDuration, "已 Update 的 Effect 持续时间应减少");
}
[Test]
public void PoisonEffect_OnStack_DoesNotExceedMaxStacks_EdgeCase()
{
var effect = new PoisonEffect();
// MaxStacks = 3初始 StackCount = 1再叠加 2 次达到上限
effect.OnStack();
effect.OnStack();
Assert.AreEqual(3, effect.StackCount);
// 再叠加,不应超过 3
effect.OnStack();
effect.OnStack();
Assert.AreEqual(3, effect.StackCount, "StackCount 不应超过 MaxStacks");
}
[Test]
public void FireEffect_OnApply_ThenExpire_DoesNotThrow()
{
var effect = new FireEffect();
Assert.DoesNotThrow(() =>
{
effect.OnApply(null);
effect.OnExpire(); // 注意:实际 API 为 OnExpire(),文档中误写为 OnRemove()
});
}
}
}