So there was this blog post here:
https://blogs.unity3d.com/2014/06/03/unit-testing-part-2-unit-testing-monobehaviours/
It recommends separating logic from MonoBehaviours because you can’t unit test MonoBehaviours because ‘Every time you try to instantiate a MonoBehaviour derivative you will get a warning saying that it’s not allowed.’
Well of course, your not supposed to instantiate MonoBehaviours, your supposed to add them to GameObjects with AddComponent.
And it seems to me that works just fine and that you can actually Unit Test a MonoBehaviour. You create a new GameObject, then AddComponent the MonoBehaviour onto that GameObject, run whatever tests you want on that added MonoBehaviour, when the test is done it automatically cleans up the GameObject and Component.
Seems to work just fine without any issues at all…
I needed Awake, Start and Update to be called in a few of them. So I wrote a utility method ‘CreateMonoBehaviourAndRun’ which creates the MonoBehaviour through AddComponent and then uses reflection to the call the private Awake, Start and Update method.
Seems to work just fine with any issues at all…
I am kind of wondering whats going on here? Why did that Unity blog post insinuate that you can’t Unit Test MonoBehaviours? Did the author of it really just not know that your supposed to use AddComponent and not Instantiate on MonoBehaviours?
Also, in case you might say ‘But your not supposed create new GameObjects in a Unit Test!’ Which seems to work just fine without any isssues. But if you need more reason then that. If you make a Unit Test through Unity’s built in Create > Editor Test C# Script option. This is the default code template for a Unit Test:
using UnityEngine;
using UnityEditor;
using NUnit.Framework;
public class NewEditorTest {
[Test]
public void EditorTest()
{
//Arrange
var gameObject = new GameObject();
//Act
//Try to rename the GameObject
var newGameObjectName = "My game object";
gameObject.name = newGameObjectName;
//Assert
//The object has a new name
Assert.AreEqual(newGameObjectName, gameObject.name);
}
}
The default code template is showing an example of making a new GameObject.
So whats up with that blog post?