Gids voor ReflectionTestUtils voor het testen van eenheden

1. Inleiding

ReflectionTestUtils maakt deel uit van Spring Test Context framework. Het is een verzameling van op reflectie gebaseerde utiliteitsmethoden die in een eenheid worden gebruikt, en integratietestscenario's om de niet-openbare velden in te stellen, niet-openbare methoden aan te roepen en afhankelijkheden te injecteren.

In deze zelfstudie bekijken we hoe we de ReflectionTestUtils bij het testen van eenheden door verschillende voorbeelden te doorlopen.

2. Maven afhankelijkheden

Laten we beginnen met het toevoegen van de nieuwste versies van alle noodzakelijke afhankelijkheden die nodig zijn voor onze voorbeelden aan onze pom.xml:

 org.springframework spring-context 5.1.2.RELEASE org.springframework spring-test 5.1.2.RELEASE-test 

De laatste spring-context, spring-test afhankelijkheden kunnen worden gedownload vanuit de Maven Central-repository.

3. Met behulp van ReflectionTestUtils om een ​​waarde van een niet-openbaar veld in te stellen

Stel dat we een instantie van een klasse met een privéveld moeten gebruiken zonder een openbare settermethode in onze unit-test.

Laten we beginnen met het maken:

openbare klasse Medewerker {privé Geheel getal-id; private String naam; // standaard getters / setters}

Normaal gesproken hebben we geen toegang tot het privéveld ID kaart om een ​​waarde toe te wijzen voor testen, omdat er geen openbare settermethode voor is.

We kunnen dan gebruiken ReflectionTestUtils.setField methode om een ​​waarde toe te kennen aan het privélid ID kaart:

@Test openbare ongeldigheid whenNonPublicField_thenReflectionTestUtilsSetField () {Werknemer werknemer = nieuwe werknemer (); ReflectionTestUtils.setField (werknemer, "id", 1); assertTrue (employee.getId (). equals (1)); }

4. Met behulp van ReflectionTestUtils om een ​​niet-openbare methode aan te roepen

Laten we ons nu voorstellen dat we een privémethode hebben werknemerToString in Werknemer klasse:

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

We kunnen een unit-test schrijven voor de werknemerToString methode zoals hieronder, ook al heeft het geen toegang van buiten een Werknemer klasse:

@Test public void whenNonPublicMethod_thenReflectionTestUtilsInvokeMethod () {Werknemer werknemer = nieuwe werknemer (); ReflectionTestUtils.setField (werknemer, "id", 1); employee.setName ("Smith, John"); assertTrue (ReflectionTestUtils.invokeMethod (werknemer, "employeeToString") .equals ("id: 1; naam: Smith, John")); }

5. Met behulp van ReflectionTestUtils om afhankelijkheden te injecteren

Stel dat u een unit-test wilt schrijven voor de volgende Spring-component met een privéveld met de @Autowired annotatie:

@Component openbare klasse EmployeeService {@Autowired private HRService hrService; openbare String findEmployeeStatus (geheel getal employeeId) {return "Employee" + employeeId + "status:" + hrService.getEmployeeStatus (employeeId); }}

We kunnen nu het HRService component zoals hieronder:

@Component openbare klasse HRService {openbare String getEmployeeStatus (Integer employeeId) {retourneer "Inactief"; }}

Laten we bovendien een nepimplementatie maken voor het HRService class door Mockito te gebruiken. We injecteren deze mock in de Medewerker Service bijvoorbeeld, en we zullen het gebruiken in onze unit-test:

HRService hrService = mock (HRService.class); wanneer (hrService.getEmployeeStatus (employee.getId ())). thenReturn ("Actief");

Omdat hrService is een privéveld zonder een openbare setter, we zullen gebruiken ReflectionTestUtils.setField methode om de mock die we hierboven hebben gemaakt in dit privéveld te injecteren.

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

Ten slotte ziet onze unit-test er ongeveer zo uit:

@Test openbare leegte whenInjectingMockOfDependency_thenReflectionTestUtilsSetField () {Werknemer werknemer = nieuwe werknemer (); ReflectionTestUtils.setField (werknemer, "id", 1); employee.setName ("Smith, John"); HRService hrService = mock (HRService.class); wanneer (hrService.getEmployeeStatus (employee.getId ())). thenReturn ("Actief"); EmployeeService employeeService = nieuwe EmployeeService (); // Injecteer mock in het privéveld ReflectionTestUtils.setField (employeeService, "hrService", hrService); assertEquals ("Werknemer" + werknemer.getId () + "status: Actief", werknemerService.findEmployeeStatus (werknemer.getId ())); }

We moeten opmerken dat deze techniek een tijdelijke oplossing is voor het feit dat we veldinjectie gebruiken in onze bonenklasse. Als we zouden zijn overgestapt op constructorinjectie, zou deze aanpak niet nodig zijn.

6. Conclusie

In deze zelfstudie hebben we laten zien hoe u ReflectionTestUtils bij het testen van eenheden door verschillende voorbeelden te bekijken.

Codevoorbeelden zijn, zoals altijd, te vinden op Github.