Search code examples
c#unit-testingnunitunity-game-enginemoq

How To Mock UnityEngine.Object.Destroy() Call?


Is there a way to verify that a UnityEngine.Object.Destroy() method is called for a specific GameObject? Since the UnityEngine.Object is no interface I cannot mock it and check for Verifiable(). I am using C#, NUnit and Moq.

For example:

UnityEngine.Object.Destroy(audioSource);

The only thing I found was this How to Mock (with Moq) Unity methods but this is not what I need.

I appreciate any help or further information about this topic!

One thing I also did was that I extract the call from above into the calling interface and verify that this method is called, but this way I only shift the problem to another layer.

public interface IAudioSource
{
    void DestroyUnityObject();
}

Then I can call the Unity Destroy method in there.

public void DestroyUnityObject()
{
    UnityEngine.Object.Destroy(mAudioSource);
}

And mock the upper method call.

audioSourceMock.Setup(s => s.DestroyUnityObject()).Verifiable();

But as I said, this only puts the problem elsewhere and I can still not verify that the Unity method is called correctly.


Solution

  • With its current state, UnityEngine doesn't support mocking with Moq. This is because Moq (or any other framework based on DynamicProxy1) can't mock member which is not overridable/implementable (in case of interfaces).

    Your best bet would be to create a wrapper as you suggested and inject it to classes that would normally use UnityEngine. This way, you can properly unit test those classes. Unfortunatelly, wrapper itself remains untestable (with Moq that is) and nothing can be done here, unless you use different isolation framework which supports static members mocking or use real implementation of UnityEngine (as regular integration test would).

    1 I explained bit of details behind this limitation in my blog post - How to mock private method?