Search code examples
c#unity-game-enginetestingstatic

Use static method in UnityTest returns error


I am currently working on a Unity project and I aml using an Utils class to store some general information (constant name, utility function, etc). I was writing some unity test for my code but when trying to access this Utils class which is static. It returns me an issue.

System.TypeInitializationException : The type initializer for 'Utils' threw an exception.

It looks like Unity is awaiting that the class should be initialize but it is a static method.

Any idea on the issue ?

Here the the code below :

The utils class :

public class Utils
{
    public static string CHARACTER = "Ball";
    public static float EPSILON = GameObject.Find(CHARACTER).transform.localScale.x / 2f;
    public static float DIRECTION_UPDATE_TIME = 0.1f;
}

The test :

[UnityTest]
public IEnumerator test_MoveDirectionIsPossibleOnBorders()
{
    SceneManager.LoadScene("TestScene_1Enemy_Static");

    GameObject character_go = GameObject.Find(Utils.CHARACTER);
    CharacterBehavior character = character_go.GetComponent<CharacterBehavior>();

    bool moved = character.updateDirection(Direction.Right);
    Assert.Equals(moved, true);

    yield return new WaitForSeconds(Utils.DIRECTION_UPDATE_TIME);
}

Solution

  • static fields/properties should be initialized by the runtime on the first access to the class (instance creation, static member access, etc.), pretty highly likely that:

    GameObject.Find(CHARACTER).transform.localScale.x / 2f;
    

    Throws an error during that process. Try commenting it out:

    public class Utils
    {
        public static string CHARACTER = "Ball";
        // public static float EPSILON = GameObject.Find(CHARACTER).transform.localScale.x / 2f;
        public static float DIRECTION_UPDATE_TIME = 0.1f;
    }
    

    Or turning into a method:

    public class Utils
    {
        public static string CHARACTER = "Ball";
        public static float EPSILON() => GameObject.Find(CHARACTER).transform.localScale.x / 2f;
        public static float DIRECTION_UPDATE_TIME = 0.1f;
    }
    

    I have not work a lot with Unity but my guess would be that GameObject.Find(CHARACTER) fails to find the object which leads to the rest of the code throwing.

    Also you can use static constructors to perform complex initialization logic (and some checks and maybe even error handling).

    Read more: