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

Unity Test Runner

-

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)

  1. 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;
    }
    }

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.