[JAVA] Wie schreibe ich Mockito

Da die Seite, auf der die Beschreibungsmethode von Mockito beim Testen mit JUnit + Mockito vorgestellt wird, geeignet ist, habe ich sie auf meine eigene Weise organisiert.

Umgebung

Eigenschaften von Mockito

Mock

Es wird verwendet, wenn Sie alle Methoden der Zielinstanz verspotten und ersetzen möchten. Im Standardzustand geben Methoden mit einem Rückgabewert für Objekte null zurück. (In der Sammlung ist es eine leere Sammlung, und in primitiven Werten ist es 0 oder falsch ...)

Es kann verspottet werden, indem die Annotation @ Mock hinzugefügt wird. Durch Zuweisen von "@ InjectMocks" zur Instanz der zu testenden Klasse Sie können eine Scheininstanz von "@ Mock" in eine Instanz eines "@ Inject" -Mitglieds in einer Instanz einfügen.

Spy

Verwenden Sie diese Option, wenn Sie nur eine bestimmte Methode der Zielinstanz ersetzen möchten. Ich bin nicht sehr gut darin. Gibt es einen Fall, in dem Sie den Getter und andere Methoden unverändert verwenden und nur eine Methode ersetzen möchten?

Sie kann durch Hinzufügen der Annotation "@ Spy" verwendet werden. Sie müssen die Instanz selbst erstellen. Es kann nicht mit "@ InjectMocks" injiziert werden.

Captor

Wird hauptsächlich zum Erfassen und Validieren von Argumentwerten verwendet. Wenn das Argument ein Objekt ist, kann es nicht mit einem Standard-Matcher wie "eq" überprüft werden. Zu diesem Zeitpunkt ist Captor wirksam.

Definieren Sie beim Erfassen von Argumenten eine Instanz der ArgumentCaptor-Klasse und geben Sie ihr "@ Captor".

Wie schreibe ich einen Basistest?

Angenommen, Sie entwerfen mit DI, fassen wir die grundlegende Beschreibung mit Mockito zusammen.

Grundlegende Richtlinien

--Stellen Sie den Modus von Mockito auf "Strict Stubs". --Mockito hat drei Modi: "Silent", "Strict" (v2 Standard) und "StrictStubs".

Und das. ――Persönlich ist es schwierig, die Beschreibungsmethode einzeln zu lernen, abhängig vom Vorhandensein oder Fehlen des Rückgabewerts und der Differenz zwischen Mock und Spy. Ich denke, es wird kompliziert zu sehen sein.

Vorbereitung

  1. Geben Sie es der Testklasse "@RunWith (MockitoJUnitRunner.StrictStubs.class)", die magisch ist, um Mockito im Test zu verwenden.
  1. Fügen Sie der Variablen der zu testenden Klasse "@ InjectMocks" hinzu.
  2. Fügen Sie der Variablen der Klasse, die Sie verspotten möchten, "@ Mock" hinzu.
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
...

@RunWith(MockitoJUnitRunner.StrictStubs.class)
public class XXTest{
  @InjectMocks
  XXInteractor target;

  @Mock
  IXXRepository repoMock;

  ...
}

Testfall

  1. Definieren Sie eine void public-Methode mit @ Test.
  2. Beschreiben Sie die Definition der Methode, mit der Sie die Scheininstanz verspotten möchten.
  3. Rufen Sie die zu testende Methode auf.
  4. Überprüfen Sie das Ergebnis.

Wenn das Testziel wie folgt ist

public class XXInteractor{
  @Inject
  IXXRepository repository;

  XXEntity fetch(String id) throws NotFoundException{
    try{
      return repository.findBy(id);
    }
    catch(UseCaseNotFoundException e){
      throw new NotFoundException();
    }
  }
}

Sie können den folgenden Test schreiben.

  private static final String ID = "ID";

  @Test
  public void testFetchSuccess() throws Exception{
    //Gibt eine normale XXEntity nur zurück, wenn eine ID als Argument angegeben wird.(Andernfalls null)
    doReturn(new XXEntity(ID))
      .when(repoMock).findBy(eq(ID));

    XXEntity result = target.fetch(ID);

    assertThat(result.getId(), is(ID));
  }

  @Test(expected = NotFoundException.class)
  public void testFetchFailureWithNotFound() throws Exception{
    doThrow(new RepositoryNotFoundException())
      .when(repoMock).findBy(eq(ID));

    target.fetch(ID);
  }

Verspotteter Anwendungsfall

Basisausgabe

Das grundlegende Verspottungsmuster ist unten gezeigt.

Gibt einen Wert mit einer verspotteten Methode zurück

//Wenn es einen Rückgabewert gibt
doReturn(new XXEntity(ID))
  .when(targetMock).fetch(eq(ID));

//Wenn es keinen Rückgabewert gibt
doNothing().when(targetMock).delete(eq(ID))

Auslösen einer Ausnahme in einer verspotteten Methode

doThrow(new XXException()).when(targetMock).fetch(eq(ID))

doThrow(new XXException()).when(targetMock).delete(eq(ID))

Ersetzen Sie die Methode der Spy-Instanz

//Gibt den Rückgabewert zurück
doReturn(new XXEntity()).when(targetSpy).fetch()

//Eine Ausnahme auslösen
doThrow(new XXException()).when(targetSpy).fetch()

Erweiterte Version

Ich möchte antworten, wenn ein Argument aufgerufen wird

doReturn(new XXEntity(ID))
  .when(targetMock).fetch(any())

Ich möchte für jeden Aufruf mit derselben Methode einen anderen Wert zurückgeben

//Fälle ohne Argumente oder Fälle, in denen Sie für jeden Aufruf mit denselben Argumenten einen anderen Wert zurückgeben möchten
//Dieser Fall kann nicht mit doReturn geschrieben werden. Schreiben Sie ihn daher im thenReturn-Format.
when(targetMock.getNextKey())
  .thenReturn("ID-1")   //Erster Aufruf
  .thenReturn("ID-2");  //Zweiter Anruf

//Fälle, die für jedes Argument unterschiedliche Werte zurückgeben(Definieren Sie jedes normal)
doReturn(new XXEntity("ID-1")).when(targetMock).fetch(eq("ID-1");
doReturn(new XXEntity("ID-2")).when(targetMock).fetch(eq("ID-2");

Ich möchte nicht-primitive Argumente validieren

Wenn das Argument primitiv ist, kann es nur mit "eq" überprüft werden. Wenn es sich bei dem Argument jedoch um ein Objekt oder ein Listenzuordnungssystem handelt, kann es nicht überprüft werden. Daher muss es mit Captor kombiniert werden.

Wenn das Testziel wie folgt ist

public class XXInteractor{
  @Inject
  IXXRepository repository;

  void update(XXEntity entity){
    repository.update(entity);
  }
}

Überprüfen Sie Folgendes.

  private static final String ID = "ID";

  @InjectMocks
  XXUseCase target;

  @Mock
  IXXRepository repoMock;

  //Captor definieren
  @Captor
  ArgumentCaptor<XXEntity> argCaptor;

  @Test
  public void testUpdateSuccess(){
    //Definieren Sie einen Mock, um die Argumente zu erfassen
    doNothing().when(repoMock).update(argCaptor.capture());

    target.update(ID);

    //Überprüfen Sie die erfassten Argumente
    assertThat(argCaptor.getValue().getId(), is(ID));
  }

Ich möchte die Argumente, die zum Schein kamen, umschreiben

Ein Fall, in dem eine Methode verspottet wird, die so etwas wie "ref" in C # implementiert und einen Teil des Arguments als Rückgabewert verwendet. Diese Methodendefinition ist nicht testbar, daher sollte sie grundsätzlich durch eine Designänderung gelöst werden. Wenn Sie den Inhalt der Instanz, die Sie als Argument erhalten haben, wirklich neu schreiben möchten, können Sie dies mit der folgenden Methode tun.

doAnswer( invocation -> {
  Object[] args = invocation.getArguments();

  //Indem Sie das Argument in diese Klasse umwandeln, können Sie diese Instanz bearbeiten.
  //In diesem Fall wird das zweite Argument neu geschrieben, also argumentiert[1]
  ((XXOutputParam) args[1]).setId("ID");
  return null; //Null, wenn der Rückgabewert ungültig ist
}).when(useCaseMock).get(any(), any())

Ich möchte die Bewegung des Mocks zurücksetzen

Rufen Sie es jedes Mal um die @ @ Before-Methode herum auf.

reset(mock);

Referenz

https://static.javadoc.io/org.mockito/mockito-core/2.23.4/org/mockito/Mockito.html

Recommended Posts

Wie schreibe ich Mockito
Wie schreibe ich Rails
Wie schreibe ich Docker-Compose
So schreiben Sie eine Migrationsdatei
Wie man guten Code schreibt
Wie schreibe ich einen Java-Kommentar
[Refactoring] So schreiben Sie Routing
Wie schreibe ich Junit 5 organisiert
Wie schreibe ich Rails Seed
Wie schreibe ich Rails Routing
Java # 6 studieren (Wie man Blöcke schreibt)
[Rails] Wie schreibe ich eine Ausnahmebehandlung?
So schreiben Sie eine Java-Variablendeklaration
So schreiben Sie leicht verständlichen Code [Zusammenfassung 3]
[Basic] So schreiben Sie ein Dockerfile Selbstlernend ②
Zusammenfassung zum Schreiben von Anmerkungsargumenten
[Einführung in Java] So schreiben Sie ein Java-Programm
[Java] Wie man Dateien ausgibt und schreibt!
So schreiben Sie den Spring AOP Point Cut Specifier
[SpringBoot] So schreiben Sie einen Controller-Test
JDBC Versprechen und Schreibbeispiel
Wie man jeden Fall mit Mockito 1x verspottet
So entwickeln Sie OpenSPIFe
[Java FX] So schreiben Sie Eclipse-Berechtigungen in build.gradle
Wie schreibe ich offline 15. Referenzfrage Antwort
So rufen Sie AmazonSQSAsync auf
Verwendung von Map
Grundlagen der Java-Entwicklung ~ Schreiben von Programmen * Übung 1 ~
Verwendung mit_option
Verwendung von fields_for
Verwendung von java.util.logging
Verwendung der Karte
Verwendung von collection_select
JUnit 5: Wie man Testfälle in enum schreibt
Wie benutzt man Twitter4J
Wie benutzt man active_hash! !!
So installieren Sie Docker
Verwendung von MapStruct
Verwendung von TreeSet
So deinstallieren Sie Rails
So installieren Sie Docker-Maschine
[Verwendung des Etiketts]
Wie man ein schattiertes Glas macht
Wie man Hash benutzt
Beispiel für die Implementierung der F06-Implementierung in Echtzeit
Wie man Code schreibt, der objektorientiertes Ruby denkt