Java: JUnit Tests mit Mockito vereinfachen

Das Mocking von Services war lange eine sehr komplizierte Sache. Mit Javassist oder speziellen Implementierungen konnte man es lösen, aber es war oft einfach nicht schnell und einfach zu benutzen. Mit Mockito kann man pro Test die Method-Calls einer Klasse überschreiben und so relativ einfach auch Test für Klassen mit Dependency Injection schreiben. Wenn man eine Service-Klasse testen möchte, die auf ein DAO zurückgreift um Daten aus der Datenbank zu laden, kann man nun einfach die DAO-Klasse mit Mockito so manipulieren, dass sie bestimmte Daten liefert ohne auf die Datenbank zu gehen und so hat man die volle Kontrolle über die Input- als auch die Output-Daten.


import org.junit.*;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import static org.mockito.Mockito.*; //to use when() without static class

public class ModelTest {

//will always return a model with id = 0 (not existing), simulating an empty/not existing database
@Mock
private TestModelDAO dao;

@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();

@Before
public void setup(){
//creating an existing dummy for id 23, so 23 will always return a valid model
TestModel dummy = new TestModel();
dummy.setId(23);
dummy.setName("blubb-23");
when(this.dao.getModel(23)).thenReturn(dummy);
}

@Test
public void getModelSimple(){
TestModel model = (new TestModelDAO()).getModel(42);
Assert.assertEquals(0, model.getId());
}

@Test
public void getModelComplexId(){
TestModel model = this.dao.getModel(23);
Assert.assertEquals(23, model.getId());
}

@Test
public void getModelComplexName(){
TestModel model = this.dao.getModel(23);
Assert.assertEquals("blubb-23", model.getName());
}

@Test
public void getModelDIExample(){
//Testing a service with constructor dependency injection
TestService service = new TestService(this.dao);
String upperName = service.getUpperCaseName(23); //name for id 23
Assert.assertEquals("BLUBB-23", upperName);
}
}


An sich sollte man solche Methoden wie getUpperCaseName nie so schreiben und immer die fertig geladene Entität rein reichen. Aber gerade bei älteren Legacy-Code findet man solche Dinge oft. Auch Tests mit fehlenden Request oder ähnlichen kann man so durchführen, ohne direkt eine gesamte HTTP-Umgebung nachbauen zu müssen.
User annonyme 2018-12-01 22:04

write comment:
Nine + = 11

Möchtest Du AdSense-Werbung erlauben und mir damit helfen die laufenden Kosten des Blogs tragen zu können?