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 Frameworkpackage is installed in the project and updated.

Assembly Definitions
- Create two
Assembly Definitions, one for theEdit Modetests and another for thePlay Modetests. Edit Modetests only run in theUnity Editorand have access to theEditorcode in addition to the game code.

- Make sure to add a reference to the
Assembly Definitionwith 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
.dllfrom theNuGetregistry manually, and add it to the Unity project as aManaged Plug-in(Which is a .NET assembly). - Go to the
NuGetpackage forNSubstitueand download the.nupkg

- Change the extension to
.zipto be able to extract its contents.

- Copy over the
.dllcorresponding to theApi Compatibility Levelset in thePlayer Settingsof your project. (Most likely.NET Standard 2.1) - Repeat the process for any dependency of the library.

- Reference the
Assemblyin theAssembly Definitionof 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}