Mock the unmockable

Mockito 2 macht Mocking finaler Klassen und Methoden möglich

Dominik Mohilo

© Mockito

Seit neun Jahren warten die Nutzer von Mockito auf diese Nachricht: Endlich ist es möglich, finale Klassen und Methoden zu mocken. Diese Neuigkeit ist auch für Kotlin-Entwickler, die das Test-Framework nutzen, nicht uninteressant. Außerdem an Bord: eine neue Engine und Java 8 Support.

Hintergrund

Wer in Unit-Tests Methoden oder Klassen isoliert von ihrer Umgebung testen möchte, braucht Mock-Objekte. Diese ersetzen im Modultest diejenigen Schnittstellen, über die das zu testende Objekt auf seine Umgebung zugreift. Beim Erstellen und Überprüfen dieser Mock-Objekte helfen Test-Frameworks wie Mockito.

Das 2007 erstellte Framework basiert auf EasyMock, dessen Code Szczepan Faber allerdings beinahe komplett umschrieb. Seit dem Umzug auf GitHub im Jahr 2012 wurde an einer Automatisierung des Release-Prozesses gearbeitet. Mit dem Umzug ging die Migration von Apache Ant auf Gradle einher. Ab 2014 begann Faber dann mit Continuous Delivery zu experimentieren.

Mockito 2.1.0 = Mockito 2

Continuous Delivery ist auch der Grund für die etwas verwirrende Versionsnummer von Mockito: 2.1.0. In GitHub wurden die Beta-Versionen für den Release-Train 2.x wie folgt markiert: 2.0.<build number>-beta. Dies führte dazu, dass Build-Tools wie Maven oder Gradle unter gewissen Umständen nicht Version 2.0.0 als die aktuellste Version identifizieren konnten. Stattdessen wurde etwa Version 2.0.1-beta als neuestes Update erkannt. Da verschiedene Workarounds das Problem nur verkompliziert hätten, entschied man sich, Version 2.1.0 als offizielles Major-Release zu veröffentlichen.

Features der neuen Version

Das wichtigste Feature der neuen Version ist sicher die Möglichkeit, finale Klassen und Methoden zu „mocken“. Bislang war es schlicht und ergreifend nicht möglich, eine finale Klasse zu mocken. Noch schlimmer: Der Versuch, eine finale Methode zu mocken, führte beim Test-Framework zu unvorhersehbarem Verhalten. Das ist nun, dank Java-Champion Rafael Winterhalter, vorbei. Bekannt ist dieser unter anderem durch sein Projekt Byte Buddy und für Mockito schrieb er die Opt-in-Implementierung, die das oben geschilderte Problem fixt.

Trotzdem weisen die Entwickler von Mockito darauf hin, dass dieses Feature noch nicht ausgereift ist und Fehler auftreten können. Daher ist es nur nutzbar, nachdem man durch die Erstellung einer Datei /mockito-extensions/org.mockito.plugins.MockMaker explizit die Nutzung beauftragt. Diese Datei muss lediglich die Zeile mock-maker-inline enthalten. Nach dem Erstellen der Datei wird Mockito diese neue Engine nutzen und folgendes ist möglich:

final class FinalClass {
    final String finalMethod() { return "something"; }
  }

  FinalClass concrete = new FinalClass(); 

  FinalClass mock = mock(FinalClass.class);
  given(mock.finalMethod()).willReturn("not anymore");

  assertThat(mock.finalMethod()).isNotEqualTo(concrete.finalMethod());

Auch Nutzer von Kotlin, die Mockito verwenden, können sich freuen: Da Klassen und Funktionen von Kotlin standardmäßig final sind, ist es durch dieses neue Feature nicht mehr nötig, diese für das Testen als open zu deklarieren oder Interfaces nur für diesen Zweck einzuführen. Über die Nutzung von Mockito 2 in Verbindung mit Kotlin hat Hadi Hariri auf seinem Blog eine Zusammenfassung geschrieben.

Auch die Unterstützung von Java 8 ist eine wichtige neue Funktion, die als Vorabversion ab Mockito 2 zur Verfügung steht. Da einige Versionen von Java 8 massive Bugs beinhalteten, raten die Mockito-Macher den Nutzern, die jüngste Version von Java 8 zu verwenden. Wenig überraschend ist es auch, dass die Engine für die Erstellung von Mocks ebenfalls geändert wurde und nun durch Byte Buddy ersetzt wurde. Die Codegenerierungsbibliothek löst die zuvor verwendete Bibliothek CGLIB ab.

Ausblick

Die Veröffentlichung von Mockito 2 markierte den Beginn der Entwicklung von Mockito 3. Beinhalten soll diese Version dann unter anderem die Vollendung des Java 8 Supports, der in Version 2 bereits als Vorab-Feature verfügbar ist. Auch die Unterstützung für Java 9 soll dann bereits enthalten sein, allerdings kommt dies auf das Datum der Veröffentlichung des Frameworks und der neuen Sprachversion an. Zudem soll es zukünftig leichter werden, den MockMaker zu konfigurieren und das Team bemüht sich, Lösungen für sämtliche bislang nicht mockbaren Szenarios zu finden.

Die Entwickler von Mockito wollen außerdem ein neues und reichhaltigeres API für das Stubbing einführen. Nähere Informationen dazu gibt es hier. Die Continuous-Delivery-Automatisierung soll ebenfalls verbessert und in eine eigenständige Bibliothek extrahiert werden.

Eine vollständige und automatisch generierte Änderungsübersicht ist auf GitHub zu finden, etwas leserfreundlicher ist der Eintrag zum Update im GitHub-Wiki von Mockito.

Geschrieben von
Dominik Mohilo
Dominik Mohilo
Dominik Mohilo studierte Germanistik und Soziologie an der Goethe-Universität in Frankfurt. Seit 2015 ist er Redakteur bei S&S-Media.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: