Unity: MonoBehaviours mit dem Humble Object Pattern testen

Unity zeigte am 3. Juni 2014 einen Ansatz, um MonoBehaviours testbarer zu entwerfen. Der Beitrag nutzt das Humble Object Pattern und verlagert die eigentliche Spiellogik in eine entkoppelte Klasse. Das Unity-spezifische MonoBehaviour bleibt als dünne Verbindungsschicht erhalten.

MonoBehaviours lassen sich nicht mit dem new-Operator instanziieren. Zusätzlich greifen viele typische Komponenten auf die Unity-API, Eingaben und die statische Zeitklasse zu. Für Unit-Tests erschwert das die Isolation. Unity beschreibt deshalb einen Entwurf, bei dem nur der Teil mit direkter Engine-Abhängigkeit im MonoBehaviour verbleibt.

Die Spiellogik wandert in eine eigene Klasse

Als Beispiel dient ein Raumschiff-Controller für eine zweidimensionale Szene. Das Schiff bewegt sich abhängig von Eingabe und Gesundheitswert, feuert in einem festen Zeitabstand und muss seine begrenzte Munition nachladen. Im ursprünglichen Entwurf liegen Eingabe, Bewegung, Zeitprüfung und das Erzeugen von Geschossen im selben MonoBehaviour.

Durch Methodenextraktion trennt Unity die Unity-API von den Regeln des Controllers. FixedUpdate reicht die Eingaben weiter, während die Klasse SpaceshipController die Logik für Bewegung, Munition und Feuerrate übernimmt. Die Prüfung der Zeit wird über eine eigene Methode wie CanFire zugänglich, damit der Test die Zeitabhängigkeit kontrollieren kann.

Interfaces halten die Engine-Abhängigkeit klein

Die ausgelagerte Klasse kommuniziert über Interfaces mit der Unity-API. Methoden zum Verschieben des Schiffs und zum Erzeugen eines Geschosses bleiben im MonoBehaviour, während die Controller-Klasse nur die abstrakten Schnittstellen kennt. Unity weist darauf hin, dass die Engine Interface-Referenzen nicht serialisiert. Sie können deshalb beim Erzeugen der Klasse oder in OnEnable gesetzt werden.

Für die Unit-Tests verwendet das Beispiel Mock-Objekte und das Arrange-Act-Assert-Muster. Ein Test setzt die verfügbare Munition auf null, löst den Feuerbefehl aus und prüft, dass kein Aufruf zum Schießen erfolgt. Die Zeitabhängigkeit wird dabei über einen Mock des Controllers neutralisiert. Als Mocking-Bibliothek kommt NSubstitute zum Einsatz, außerdem verweist Unity auf die Unity Test Tools. Der Ansatz ergänzt den älteren Unity-Beitrag zum Mono-JIT-Fehler im Editor um die Perspektive auf testbare Engine-Codearchitektur.

Weitere News

Weitere News

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein