Leitfaden zu ReflectionTestUtils zum Testen von Einheiten

1. Einführung

ReflectionTestUtils ist Teil des Spring Test Context-Frameworks. Es ist eine Sammlung für reflektionsbasierte Dienstprogrammmethoden, die in einer Unit verwendet werden, und Szenarien zum Integrationstest, um die nicht öffentlichen Felder festzulegen, nicht öffentliche Methoden aufzurufen und Abhängigkeiten einzubringen.

In diesem Lernprogramm erfahren Sie, wie wir die ReflectionTestUtils beim Komponententest verwenden können, indem wir einige Beispiele durchgehen.

2. Abhängigkeiten von Maven

Beginnen wir mit dem Hinzufügen der neuesten Versionen aller notwendigen Abhängigkeiten für unsere Beispiele in unserer pom.xml :

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.2.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.1.2.RELEASE</version>
    <scope>test</scope>
</dependency>

Die neuesten __https://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.springframework%22%20AND%20a%3A%22spring-context%22[Frühlingskontext], spring-test __dependencies können vom Maven heruntergeladen werden Zentrales Repository

  1. Verwenden Sie ReflectionTestUtils , um einen Wert eines nicht öffentlichen Felds festzulegen

Angenommen, wir müssen in unserem Unit-Test eine Instanz einer Klasse mit einem privaten Feld ohne öffentliche Setter-Methode verwenden.

Beginnen wir mit der Erstellung:

public class Employee {
    private Integer id;
    private String name;

   //standard getters/setters
}

Normalerweise können wir nicht auf das private Feld id zugreifen, um einen Testwert zuzuweisen, da es keine öffentliche Setter-Methode dafür gibt.

Wir können dann die Methode ReflectionTestUtils.setField verwenden, um dem privaten Member id einen Wert zuzuweisen:

@Test
public void whenNonPublicField__thenReflectionTestUtilsSetField() {
    Employee employee = new Employee();
    ReflectionTestUtils.setField(employee, "id", 1);

    assertTrue(employee.getId().equals(1));
}

4. Verwenden von ReflectionTestUtils zum Aufrufen einer nicht öffentlichen Methode

Stellen wir uns nun vor, dass wir eine private Methode employeeToString in der Klasse Employee haben:

private String employeeToString(){
    return "id: " + getId() + "; name: " + getName();
}

Wir können einen Komponententest für die Methode employeeToString wie folgt schreiben, auch wenn sie keinen Zugriff außerhalb einer Klasse Employee hat:

@Test
public void whenNonPublicMethod__thenReflectionTestUtilsInvokeMethod() {
    Employee employee = new Employee();
    ReflectionTestUtils.setField(employee, "id", 1);
    employee.setName("Smith, John");

    assertTrue(ReflectionTestUtils.invokeMethod(employee, "employeeToString")
      .equals("id: 1; name: Smith, John"));
}

5. Verwenden von ReflectionTestUtils zum Injizieren von Abhängigkeiten

Angenommen, Sie möchten einen Komponententest für die folgende Spring-Komponente schreiben, die ein privates Feld mit der Annotation @ Autowired hat:

@Component
public class EmployeeService {

    @Autowired
    private HRService hrService;

    public String findEmployeeStatus(Integer employeeId) {
        return "Employee " + employeeId + " status: " + hrService.getEmployeeStatus(employeeId);
    }
}

Wir können jetzt die HRService -Komponente wie folgt implementieren:

@Component
public class HRService {

    public String getEmployeeStatus(Integer employeeId) {
        return "Inactive";
    }
}

Außerdem erstellen wir eine Scheinimplementierung für die HRService -Klasse, indem Sie Mockito verwenden.

Wir werden diesen Mock in die EmployeeService -Instanz injizieren und in unserem Unit-Test verwenden:

HRService hrService = mock(HRService.class);
when(hrService.getEmployeeStatus(employee.getId())).thenReturn("Active");

Da hrService ein privates Feld ohne öffentlichen Setter ist, verwenden wir die Methode ReflectionTestUtils.setField , um den oben erstellten Mock in dieses private Feld einzufügen.

EmployeeService employeeService = new EmployeeService();
ReflectionTestUtils.setField(employeeService, "hrService", hrService);

Schließlich wird unser Komponententest folgendermaßen aussehen:

@Test
public void whenInjectingMockOfDependency__thenReflectionTestUtilsSetField() {
    Employee employee = new Employee();
    ReflectionTestUtils.setField(employee, "id", 1);
    employee.setName("Smith, John");

    HRService hrService = mock(HRService.class);
    when(hrService.getEmployeeStatus(employee.getId())).thenReturn("Active");
    EmployeeService employeeService = new EmployeeService();

   //Inject mock into the private field
    ReflectionTestUtils.setField(employeeService, "hrService", hrService);

    assertEquals(
      "Employee " + employee.getId() + " status: Active",
      employeeService.findEmployeeStatus(employee.getId()));
}

6. Schlussfolgerung

In diesem Lernprogramm haben wir gezeigt, wie Sie ReflectionTestUtils beim Komponententest verwenden, indem Sie einige Beispiele durchgehen.

Codebeispiele finden Sie wie immer unter https://github.com/eugenp/tutorials/tree/master/testing-modules/spring-testing Über Github