Usually, private members should not be tested. Because they do not matter. It’s absolutely valid to refactor all private methods and member variables. As long as the public interface is working as expected, everything is good.
There is one exception in Unity: private members which are marked as [SerializeField]
Serialized fields can be changed in the editor. This means, they are actually public and need to be tested.
There is just one problem: We can’t access them from our test class, because officially they are private. Making them public might not be a good idea, because we don’t support changes at runtime.
Reflection would be possible, but it’s tedious. Therefore I prefer the internal access modifier.
Internal members
Internal members are accessible only within the same assembly. To make them accessible for the test framework, we need to extend the visibility with the keyword “InternalsVisibleTo”.
I assume that you already have different assembly definition files for your code and your tests.
Put a file “AssemblyInfo.cs” next to the asmdef file of your code. Add the following content and replace “TestAssembly” with the name of your test assembly.
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("TestAssembly")]
Now you can access the internal members just like public members in your test scripts.
Possible issues
Be careful though: This approach exposes private members to all classes in your assembly. The internal member might be used inadvertently in your production code as well. Especially when you are working on a big project, this happens very easily.
Naming conventions might be helpful. Instead of directly exposing the member variable, you could add a property with a preceding “Test”.
[SerializeField]
private int m_something;
internal int TestSomething{ get => m_something; set => m_something = value; }