Search Unity

Question How to mock GameObject for UnitTesting

Discussion in 'Testing & Automation' started by Alex_2022, Feb 16, 2023.

  1. Alex_2022

    Alex_2022

    Joined:
    May 4, 2022
    Posts:
    16
    I am using the Unity Testframework with Moq for mocking purposes.

    I need to test a class 'A' that uses a method "GetListOfGameObjects()" of another class 'B'. In the business logic of class 'A', the list of GameObjects will be iterated through and a bunch of properties of each GameObject will be read, including 'native' GameObject-properties like 'transform' or 'transform.position'.

    To build the GameObjects for test, i tried to mock them using Moq:

    Code (CSharp):
    1.         Mock<GameObject> m = new Mock<GameObject>();
    2.         m.Setup(p => p.transform.position).Returns(new Vector2(15, 10));
    3.         m.Setup(p => p.name).Returns("m");
    4.         m.Setup(p => p.GetComponent<IKillAble>()).Returns<IKillAble>(k => {
    5.             Mock<IKillAble> m = new Mock<IKillAble>();
    6.             m.Setup(p => p.GetCurrentHealth()).Returns(10);
    7.             return m.Object;
    8.         });
    9.         fleetInMissionManager.AddActiveShip(m.Object);
    However, there is an error because you can not mock sealed classes like GameObject:

    upload_2023-2-16_22-1-23.png

    I searched for a long time but can not find any hint of how to mock a GameObject-class. One forum-entry mentioned that if you have to mock a sealed class, this is indicating that you have a conceptual problem in your architecture.

    So i am confused. Is it wrong to manage a List of GameObjects? Or how are you supposed to setup the Unit tests?

    Thx in advance!
     
  2. rdjadu

    rdjadu

    Joined:
    May 9, 2022
    Posts:
    116
    Yeah, there's not a lot of C# mocking frameworks that can mock concrete methods. JustMock (the paid version) comes to mind as one of the few.

    In general, you have two options here with Unity:
    1. Write your tests such that they do use Unity's engine functionality.
    2. Write your code such that you have an abstraction in-between your logic and Unity such that your tests can insert themselves here.
    Personally, I vastly prefer 1. Makes it harder to get the tests stable but also means the tests run way closer to what your actual game does. And it allows testing a whole lot of code that isn't really very test-friendly otherwise.
     
  3. Alex_2022

    Alex_2022

    Joined:
    May 4, 2022
    Posts:
    16
    I see. Thank you for your advice.

    I need to think about how much effort i want to put into the tests. The game is still in prototype stage and i need to get the prototype working as fast as possible. On the other hand, the prototype already contains a lot of game logic that needs to be tested.... :(