You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity单元测试初始化失败排查:空引用错误与测试模式选择

问题解决与模式选择

一、NullReferenceException 问题修复

你遇到的报错并非playerNameInput2本身为null,而是TMP组件创建时缺少必要的依赖对象:直接通过AddComponent<TMP_InputField>()添加的组件,其内部用于显示文本的textComponent并未自动生成,导致访问.text属性时触发空引用异常。

修复后的测试代码

using System.Collections;
using NUnit.Framework;
using TMPro;
using UnityEngine;
using UnityEngine.TestTools;
using UnityEngine.UI;

public class Playtests_StartScene
{
    [UnityTest]
    public IEnumerator Start_InitializesUIElements()
    {
        // 创建测试对象并挂载脚本
        GameObject startSceneObject = new GameObject();
        var startSceneScript = startSceneObject.AddComponent<StartSceneScript>();

        // 初始化TMP_InputField1并关联文本载体
        var input1 = startSceneObject.AddComponent<TMP_InputField>();
        var input1Text = new GameObject("Input1Text").AddComponent<TextMeshProUGUI>();
        input1Text.transform.SetParent(startSceneObject.transform);
        input1.textComponent = input1Text;
        startSceneScript.playerNameInput1 = input1;

        // 初始化TMP_InputField2并关联文本载体
        var input2 = startSceneObject.AddComponent<TMP_InputField>();
        var input2Text = new GameObject("Input2Text").AddComponent<TextMeshProUGUI>();
        input2Text.transform.SetParent(startSceneObject.transform);
        input2.textComponent = input2Text;
        startSceneScript.playerNameInput2 = input2;

        // 初始化所有TMP_Text组件
        var warningText = new GameObject("WarningText").AddComponent<TMP_Text>();
        warningText.transform.SetParent(startSceneObject.transform);
        startSceneScript.warningText = warningText;

        var blueShipText = new GameObject("BlueShipText").AddComponent<TMP_Text>();
        blueShipText.transform.SetParent(startSceneObject.transform);
        startSceneScript.blueShipCountText = blueShipText;

        var redShipText = new GameObject("RedShipText").AddComponent<TMP_Text>();
        redShipText.transform.SetParent(startSceneObject.transform);
        startSceneScript.redShipCountText = redShipText;

        // 初始化Slider组件(设置value无需额外子组件)
        startSceneScript.blueShipCountSlider = startSceneObject.AddComponent<Slider>();
        startSceneScript.redShipCountSlider = startSceneObject.AddComponent<Slider>();

        // 调用Start方法
        startSceneScript.Start();

        // 断言验证初始化结果
        Assert.AreEqual("Blue Team", startSceneScript.playerNameInput1.text);
        Assert.AreEqual("Red Team", startSceneScript.playerNameInput2.text);
        Assert.AreEqual("", startSceneScript.warningText.text);
        Assert.AreEqual(1, Mathf.RoundToInt(startSceneScript.blueShipCountSlider.value));
        Assert.AreEqual(1, Mathf.RoundToInt(startSceneScript.redShipCountSlider.value));
        Assert.AreEqual("1", startSceneScript.blueShipCountText.text);
        Assert.AreEqual("1", startSceneScript.redShipCountText.text);

        yield return null;
    }
}

额外优化建议

在StartSceneScript中添加空引用检查,避免实际运行时因组件未赋值报错:

public void Start()
{
    playerNameInput1?.text = "Blue Team";
    playerNameInput2?.text = "Red Team";
    warningText?.text = "";
    
    blueShipCountSlider?.SetValueWithoutNotify(1);
    redShipCountSlider?.SetValueWithoutNotify(1);
    
    ShowSliderValue();
}

public void ShowSliderValue()
{
    if (blueShipCountSlider != null)
        GlobalVariables.blueShipsCount = Mathf.RoundToInt(blueShipCountSlider.value);
    if (redShipCountSlider != null)
        GlobalVariables.redShipsCount = Mathf.RoundToInt(redShipCountSlider.value);
    
    blueShipCountText?.text = GlobalVariables.blueShipsCount.ToString();
    redShipCountText?.text = GlobalVariables.redShipsCount.ToString();
}

二、编辑器模式 vs Play模式测试选择

针对你的UI初始化逻辑测试场景,两种模式的适用场景如下:

  • 编辑器模式测试:
    优势:无需启动Play模式,执行速度快;可直接访问编辑器API,适合测试场景序列化、资源加载类逻辑。
    劣势:无法模拟完整运行时环境,依赖生命周期的逻辑测试准确性不足。
  • Play模式测试:
    优势:完全模拟游戏运行时状态,能准确验证组件生命周期(如Start)、UI交互等逻辑,匹配你的测试需求。
    劣势:启动Play模式会增加测试执行时间。

结论:你的测试场景更适合使用Play模式测试,它能确保测试结果与实际游戏运行状态完全一致。

内容的提问来源于stack exchange,提问作者Jaydek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:22:57