Search Unity

Constructor Alternative

Discussion in 'Testing & Automation' started by Dextozz, Apr 24, 2022.

  1. Dextozz

    Dextozz

    Joined:
    Apr 8, 2018
    Posts:
    493
    I'm trying to test a top-level game manager script. It's a MonoBehaviour that will sit near the top of the game's hierarchy. Naturally, in the current iteration, it has some inspector references. What's the best practice when injecting these?

    Code sample:
    Code (CSharp):
    1. public class GameManager : MonoBehaviour
    2. {
    3.     [Header("Prefabs")]
    4.     [SerializeField] private Player playerPrefab;
    5.     [SerializeField] private GameObject fieldPrefab;
    6.  
    7.     private Player spawnedPlayer;
    8.     private GameObject spawnedField;
    9.    
    10.     public void InitGame()
    11.     {
    12.         spawnedPlayer = Object.Instantiate(playerPrefab);
    13.         spawnedField = Object.Instantiate(fieldPrefab);
    14.     }
    15. }
    Option A:
    Create an "Init" method for injecting whatever is an inspector reference just for the purpose of testing. Yuck. Creating methods only for tests. I'm really against doing this.

    Option B:
    Reflection. Find the fields by name and inject valid values into the object like that. This is fine-ish but tends to break often due to looking for fields by name.

    Option C:
    A new testing scene with a properly configured object. Yuck, again. This would require a scene per MonoBehaviour object, which is just unrealistic.
     
  2. sbergen

    sbergen

    Joined:
    Jan 12, 2015
    Posts:
    53
    I'd suggest using some dependency injection framework. Check out e.g. Zenject/Extenject. VContainer also looks promising: it seems like the devs learned something from the complexity of Zenject, but I haven't really had the time to look into it in depth.
     
  3. Dextozz

    Dextozz

    Joined:
    Apr 8, 2018
    Posts:
    493
    I've been meaning to take a look at Zenject for a few months now but never really needed it. Now I might. I'll be taking a closer look, thanks!