Search Issue Tracker
By Design
Votes
1
Found in
5.6.4p2
Issue ID
982381
Regression
No
NullReferenceException error appears after running test with nested coroutines
Steps to reproduce:
1. Open attached “CoroutineTest.zip” Unity project
2. Open Window->Test Runner
3. Click Run All in PlayMode Editor Tests
Expected results:
No error appears
Actual results:
NullReferenceException error appears
Reproduced in: 2018.1.0a5, 2017.3.0p1, 2017.2.1p1, 2017.1.3f1, 5.6.5f1, 5.6.0f3
Note: Could not test versions after 2018.1.0a5 because same reproduction steps cause a crash (Case 982783)
Error:
NullReferenceException
UnityEngine.MonoBehaviour.StartCoroutine (IEnumerator routine) (at /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/MonoBehaviourBindings.gen.cs:62)
CoroutineTest+<CoroutineTry>c__Iterator0.MoveNext () (at Assets/Tests/CoroutineTest.cs:14)
UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) (at /Users/builduser/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
Add comment
All about bugs
View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.
Latest issues
- Low FPS persists when re-entering Play mode after an extended session in a specific project
- ListView list items in UIToolkit get stuck when reorderMode is set to Animated and they are reordered using two or more fingers on touch devices
- Editor or player crashes when using a deeply nested Particle System with a sub-emitter that has multiple references
- [Metal][iOS] Application freeze when switching between portrait and landscape orientation on iPad Pro
- Tile Palette grid is moved after entering Play Mode
Resolution Note:
The issue causing the failure is that the test class cannot be a MonoBehavior, as it the test class is constructed, but not instantiated. An alternative solution to this is to just yield the method that needs to run as a corutine, then the test runner picks it up and runs it.
public class CoroutineTest2
{
[UnityTest]
public IEnumerator CoroutineTry()
{
Debug.Log("Starting Coroutine Test!");
yield return TestTwo();
Debug.Log("This message should be shown last");
}
IEnumerator TestTwo()
{
yield return null;
Debug.Log("Running in coroutine");
yield return null;
}
}
An alternative solution is to split the mono behavior away from the test, create a new game object and then add the mono behavior to that. E.g.
public class CoroutineTest
{
[UnityTest]
public IEnumerator CoroutineTry()
{
Debug.Log("Starting Coroutine Test!");
var go = new GameObject();
var mb = go.AddComponent<MonoBehaviorWithCorutine>();
mb.RunAsCorutine();
yield return null;
Debug.Log("This message should be shown last");
}
}
public class MonoBehaviorWithCorutine : MonoBehaviour
{
public void RunAsCorutine()
{
StartCoroutine(TestTwo());
}
IEnumerator TestTwo()
{
yield return null;
Debug.Log("Running in coroutine");
yield return null;
}
}