Writing Unit Tests with NSubstitute (Unity)
Use the Unity Test Framework, NUnit and NSubstitute to test your game.
References
- About Unity Test Framework
- What Is NUnit
- Assert.Greater
- NSubstitute
- Managed plug-ins
- NSubstitute NuGet
Table of Content
- References
- Table of Content
- Install the Unity Test Framework
- Assembly Definitions
- Tests Files
- Add NSubstitute
- Tests Examples
Install the Unity Test Framework
- Make sure the
Test Framework
package is installed in the project and updated.
Assembly Definitions
- Create two
Assembly Definitions
, one for theEdit Mode
tests and another for thePlay Mode
tests. Edit Mode
tests only run in theUnity Editor
and have access to theEditor
code in addition to the game code.
- Make sure to add a reference to the
Assembly Definition
with the code for your game, so you can tests its classes.
Tests Files
- Create test files using the template or write your own from scratch.
Add NSubstitute
- You will need to obtain the
.dll
from theNuGet
registry manually, and add it to the Unity project as aManaged Plug-in
(Which is a .NET assembly). - Go to the
NuGet
package forNSubstitue
and download the.nupkg
- Change the extension to
.zip
to be able to extract its contents.
- Copy over the
.dll
corresponding to theApi Compatibility Level
set in thePlayer Settings
of your project. (Most likely.NET Standard 2.1
) - Repeat the process for any dependency of the library.
- Reference the
Assembly
in theAssembly Definition
of your tests, to be able to useNSubstitute
.
Tests Examples
[UnityTest]
tests allow you to skip a frame in the simulation by doingyield return null
, or skip many doingyield return new WaitForSeconds()
.[Test]
tests don't run the simulation of the game, you can't skip frames.
1[UnityTest] 2public IEnumerator test__on_trigger_enter__invokes_gun_reclaim_bullet() 3{ 4 var gun = Substitute.For<IGun>(); 5 6 var bullet = CreateBullet(); 7 bullet.gun = gun; 8 bullet.speed = 20.0f; 9 10 var limits = CreateProjectilesLimit(); 11 12 yield return new WaitForSeconds(0.05f); 13 14 gun.Received().ReclaimBullet(bullet); 15 16 GameObject.Destroy(bullet.gameObject); 17 GameObject.Destroy(limits.gameObject); 18} 19 20public static Bullet CreateBullet() 21{ 22 var obj = new GameObject("Bullet"); 23 obj.layer = LAYER_PLAYER_PROJECTILES; 24 25 var rigidbody = obj.AddComponent<Rigidbody>(); 26 rigidbody.useGravity = false; 27 28 var collider = obj.AddComponent<BoxCollider>(); 29 collider.size = new Vector3(1.0f, 1.0f, 1.0f); 30 collider.isTrigger = true; 31 32 var bullet = obj.AddComponent<Bullet>(); 33 34 return bullet; 35} 36 37private BoxCollider CreateProjectilesLimit() 38{ 39 var obj = new GameObject("ProjectilesLimit"); 40 obj.layer = Utils.LAYER_PROJECTILES_LIMITS; 41 42 obj.transform.position = new Vector3(0.0f, 0.0f, 1.1f); 43 44 var collider = obj.AddComponent<BoxCollider>(); 45 collider.size = new Vector3(5.0f, 5.0f, 1.0f); 46 collider.isTrigger = true; 47 48 return collider; 49}