- Home /
Can you unit test MonoBehavior (and classes derived from it)
I'm trying to setup unit testing for my project. Although most of my logic is going to reside in regular C# classes, certain things are going to have to live in MonoBehaviors (for instance, I'd like to test whether the component gets attached, or whether it even makes a call to the game logic in certain scenarios).
So I tried setting up nUnit and just including a reference to Assembly-CSharp and testing that. No luck, unity won't let you run its dlls outside of Unity.
So I went to TestRunner and tried to create an EditMode Test folder, and create a simple test
[Test]
public void UnitTest1SimplePasses() {
Assert.IsTrue(new GameStateManager().Test());
}
But this fails because Unity can't see the GameStateManager class (it's defined in the Assets folder). While Visual Studio compiles correctly, Unity displays:
Assets/EditModeTests/UnitTest1.cs(10,27): error CS0246: The type or namespace name `GameStateManager' could not be found. Are you missing an assembly reference?
Looking at the videos from the Unite 2017 conference (https://www.youtube.com/watch?v=MWS4aSO7HAo), she's clearly doing some sort of manipulation with Unity classes, so is MonoBehavior just special? Am I doing something wrong in my setup, or is it really impossible to unit test logic in those classes? Thank you for any help.
I have unit tests setup in my object pooler it also tests on objects with monobehaviour, maybe you can take a look at the setup?
It seems like I can't actually run your tests, Do you run your tests through Visual Studio/$$anonymous$$ono or through Unity?
Through unity, 'Windows' -> 'Test Runner' In here you see all the playmode tests listed.
https://docs.unity3d.com/$$anonymous$$anual/testing-editortestsrunner.html
Answer by Kolichikov · Jul 15, 2018 at 02:35 AM
So the answer turned out to be extremely simple -> Unity wants Edit tests to be treated like any other editor file, and hence must reside in an Editor folder.
Doing this allows you to code logic tests for all of your scripts that inherit from MonoBehaviors, and run them as simple unit tests from inside the Unity Test Runner (Unity will still not allow you to run them from Visual Studio, but it's quick an easy).
Just remember that Unity will throw warnings if you instantiate components with new, but won't fail, so you don't need to actually deal with any setup outside of your class. For instance, this simple test passes
[Test]
public void Script1SimplePasses() {
var s = new GameStateManager();
Assert.IsTrue(s.Test());
}
if Test returns true, and fails if it returns false. In both cases the TestRunner will give the following warning:
You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all
Just in case anyone else wants to follow along, I followed the video here: https://www.youtube.com/watch?v=2oXRx2hc-fI
You should take that warning seriously. Anything related to the engine will not work when you create a $$anonymous$$onoBehaviour derived class with new. So you can never access "transform", "gameObject", "GetComponent", and even "name" inside your class as those are all stored on the native C++ side. When you create your class with new you only create a managed part of your class which will turn into a fake-null instance without the native part.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Manipulate EditorApplication.currentScene in a generic script 1 Answer
C# code structure question 1 Answer