Statische Methoden mocken mit Mockito

“Unser Wissen ist das Resultat unserer Erfahrungen, unsere Erfahrungen sind das Resultat unserer Dummheit.”

Sacha Guitry

Hin und wieder entdeckt man als Software Entwickler ein Feature in einer Bibliothek wieder, dass man schon zweimal vergessen hat. Wenn man dieses wiederentdeckte Wissen mit einem Kollegen teilen kann, dann ist es nicht nur schön sondern verbessert auch noch die Qualität der täglichen Arbeit.

Das hier beschriebene Feature ist die Möglichkeit mit Mockito auch statische Methoden zu mocken. Lange Zeit war dies mit Mockito nicht möglich und es mussten andere Bibliotheken oder Erweiterungen zu Mockito genutzt werden.

Statische Methoden müssen selten gemockt werden, da sie in der Regel nur für die Implementierung von Hilfsmethoden verwendet werden. Enthält eine Anwendung sehr viele (öffentlichen) statische Methoden, dann kann grundsätzlich von einer schlechten Modellierung der Anwendungsdomäne ausgegangen werden. Eigene Hilfsmethoden sollten keine externen Resourcen (Datenbanken, Remote-Services, etc.) verwenden, damit die Unit-Tests schnell und ohne Störungen abgearbeitet werden können.

Das hier vorgestellten Beispiel behandelt den häufigsten Fall von statischen Methoden, die in den eigenen Unit-Tests gemockt werden soll. Eine externe Bibliothek bietet ihren Dienst nur über eine statische Methode an und dieser Aufruf ist extrem teuer.

public Person find(String gina) {
  Person result = ThirdPartyTool.getOpenAncestors(gina);
  // ...
}

Hier wird in der find Methode der teure Aufruf ThirdPartyTool.getOpenAncestors verwendet. Damit diese Methode ohne externe Abhängigkeit getestet werden kann, muss sie gemockt werden.

try (MockedStatic<ThirdPartyTool> mockedStatic = Mockito.mockStatic(ThirdPartyTool.class)) {
      mockedStatic.when(ThirdPartyTool::getOpenAncestors).thenReturn(openAnchestorapi);
  Person person = anchestorService.find("GEBDAS-1139353466"));
  assertNotNull(person);
  assertEquals("Margarethe Dorothee Marie /Trüttner/", person.getName());
}

In Mockito können statische Methoden mit Hilfe der Klasse MockedStatic getestet werden. Erzeugt wird eine Instanz dieser Klasse mit der Methode mockStatic. Der Parameter ist die Klasse, deren statische Methode gemockt werden soll. Das Verhalten der statische Methoden wird dann über die when Methode der MockedStatic Instanz beschrieben. Ihre Verwendung entspricht der Mockito.when Methode.

Interessant bei der Verwendung ist der Try-Resource Block. Die Modifikation des Verhaltens gilt nur innerhalb des Blocks und wird automatisch beim Verlassen des Block verworfen. Ansonsten kann es Probleme geben, dass der Mock auch an anderen Stellen weiterhin das Verhalten der statische Methode verändert.

Sollte der Unit-Tests nicht gleich funktionieren, dann kann es daran liegen, dass die mockito-inline Bibliothek nicht eingebunden wurde.

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-inline</artifactId>
  <scope>test</scope>
</dependency>

Leave a Comment