[JAVA] Tipps zum Testen mit Mock für Klassen mit @value

Es ist der 9. Tag des Adventskalenders der Tokyo Science University 2019.

Dieses Mal werde ich über die Methode / Tipps zum Testen einer Klasse schreiben, die die Annotation @ Value im Java Framework Spring verwendet.

Was ist "@ Value"?

Die Annotation "@ Value" ist eine Annotation, die verwendet wird, wenn Sie einen Wert aus einer anderen Datei einfügen möchten. Für Spring Boot Wenn die Standardeinstellungen verwendet werden, werden die in application.yml oder application.properties beschriebenen Werte gelesen und eingefügt.

Insbesondere ist es in diesem Format. Schreiben Sie zuerst den Wert in application.yml.

application.yml


sample.threshold : 1

Und im Argument der Anmerkung

@Value("${Schlüssel}")

Fügen Sie dann die Annotation "@ Value" zu den Feldern und Argumenten in der Klasse hinzu.

Speziell

HogeCoordinator.java


@Service
public class HogeCoordinator {

  @value("${sample.threshold}")
  private Integer threshold;

  @Autowired
  private HogeService hogeService;

  public void hoge() {
    hogeService.fuga(threshold);
  }
}

Es ist so ein Bild. Wenn Sie "@ value (" $ {sample.threshold} ")" in den Feldschwellenwert der HogeCoordinator-Klasse schreiben, wird 1 aus dem in application.yml beschriebenen Schlüssel gelesen und bei Ausführung der Anwendung injiziert.

Dies hat den Vorteil, dass anwendungsspezifische Werte in einer einzigen Datei erfasst und verwaltet werden können.

Testen auf Klassen mit @ Value

Dann ist es eine Testmethode für die Klasse unter Verwendung von "@ Value" des Hauptfachs.

Das Testziel ist HogeCoordinator.java. Wenn Sie bei Verwendung von "@ Value" den folgenden allgemeinen Test schreiben, wird der Wert nicht in das Ziel injiziert, für das "@ Value" angegeben ist.

FailedHogeCoordinatorTest.java


public class FailedHogeCoordinatorTest {

  @InjectMocks
  private HogeCoordinator hogeCoordinator;

  @Mock
  private HogeService hogeService;

  @Before
  public void setup() {
    MockitoAnnotations.initMocks(this);
  }

  //Unten weggelassen
}

Verwenden Sie daher die setField-Methode der ReflectionTestUnits-Klasse. Geben Sie im Argument der Methode die Zielinstanz, den zu injizierenden Feldnamen und den zu injizierenden Wert an.

Um diese Methode verwenden zu können, muss eine Instanz von HogeCoordinator erstellt werden. Halten Sie sie also neu.

Wenn Sie einen darauf basierenden Test schreiben, sieht er folgendermaßen aus.

SuccessHogeCoordinatorTest.java


public class SuccessHogeCoordinatorTest {

  @InjectMocks
  private HogeCoordinator hogeCoordinator = new HogeCoordinator();

  @Mock
  private HogeService hogeService;

  @Before
  public void setup() {
    ReflectionTestUnits.setField(hogeCoordinator, "threshold", 1);
    MockitoAnnotations.initMocks(this);
  }

  //Unten weggelassen
}

Auf diese Weise wird der Wert mit "@ Value" in das Feld eingefügt.

Der Trick besteht darin, dass Sie eine Instanz der Klasse erstellen müssen, die den Mock zur Testzeit injiziert. Daher ist es am besten, beim DI keine Konstruktorinjektion durchzuführen.

Die HogeCoordinator-Klasse, die Gegenstand dieses Tests ist, ist DI mit @ Autowired. Wenn Sie jedoch eine Konstruktorinjektion mit Lomboks @ RequiredArgsConstructor durchführen (siehe unten), erhöht sich die Anzahl der Konstruktorargumente. Dies macht das Erstellen einer Instanz umständlich.

HogeCoordinator.java


@Service
@RequiredArgsConstructor
public class HogeCoordinator {

  @value("${sample.threshold}")
  private Integer threshold;

  private final HogeService hogeService;

  public void hoge() {
    hogeService.fuga(threshold);
  }
}

Daher ist es beim Injizieren in eine zu testende Klasse mit der setField-Methode der ReflectionTestUnits-Klasse einfacher, die Konstruktorinjektion zu vermeiden.

Zusammenfassung

Verwenden Sie beim Testen einer Klasse mit "@ Value" die setField-Methode der ReflectionTestUnits-Klasse, um den Wert einzufügen. Wenn zu diesem Zeitpunkt der DI der zu testenden Klasse auf eine andere Methode als die Konstruktorinjektion eingestellt ist, ist es einfacher, während des Tests eine Instanz zu generieren, und es ist einfacher zu testen.

schließlich

Ich habe diesmal eine Verbindung zu OB und habe mich daher entschlossen, am Adventskalender teilzunehmen. Ich bin @piffett dankbar, dass ich zum ersten Mal einen wertvollen Ort für die Teilnahme am Adventskalender gefunden habe. Vielen Dank.

Verweise

Offizielles Frühlingsdokument (@Value)

Offizielle Dokumente des Frühlings (Allgemeine Testdienstprogramme)

Recommended Posts

Tipps zum Testen mit Mock für Klassen mit @value
Hinweise zur Verwendung von BLE in iOS-Apps
Umgebungskonstruktionsverfahren für die Verwendung von PowerMock mit JUnit
Testcode mit Mock mit JUnit (EasyMock Center)
Tipps für java.nio.file.Path
Testen mit com.google.testing.compile