Guide to ReflectionTestUtils for Unit Testing
1. Introduksjon
ReflectionTestUtils er en del av Spring Test Context framework. Det er en samling for refleksjonsbaserte verktøymetoder som brukes i en enhet, og integrasjonstest scenarier for å angi ikke-offentlige felt, påkalle ikke-offentlige metoder og injisere avhengigheter.
I denne opplæringen tar vi en titt på hvordan vi kan bruke ReflectionTestUtils i enhetstesting ved å gå gjennom flere eksempler.
2. Maven-avhengigheter
La oss starte med å legge til de nyeste versjonene av alle nødvendige avhengigheter som trengs for eksemplene våre pom.xml:
org.springframework spring-context 5.1.2.RELEASE org.springframework spring-test 5.1.2.RELEASE test
Det siste vår-kontekst, vår-test avhengigheter kan lastes ned fra Maven Central repository.
3. Bruke ReflectionTestUtils for å sette en verdi av et ikke-offentlig felt
Anta at vi må bruke en forekomst av en klasse som har et privat felt uten en offentlig settermetode i vår enhetstest.
La oss starte med å lage det:
offentlig klasse ansatt {privat heltal id; privat strengnavn; // standard getters / setters}
Normalt får vi ikke tilgang til det private feltet id å tilordne en verdi for testing, fordi det ikke er en offentlig settermetode for den.
Vi kan da bruke ReflectionTestUtils.setField metode for å tildele en verdi til det private medlemmet id:
@Test offentlig ugyldig nårNonPublicField_thenReflectionTestUtilsSetField () {Ansatt ansatt = ny ansatt (); ReflectionTestUtils.setField (ansatt, "id", 1); assertTrue (medarbeider.getId (). tilsvarer (1)); }
4. Bruke ReflectionTestUtils å påkalle en ikke-offentlig metode
La oss nå forestille oss at vi har en privat metode ansattToString i Ansatt klasse:
private strengmedarbeiderToString () {return "id:" + getId () + "; navn:" + getName (); }
Vi kan skrive en enhetstest for ansattToString metoden som nedenfor, selv om den ikke har tilgang utenfra en Ansatt klasse:
@Test offentlig ugyldig nårNonPublicMethod_thenReflectionTestUtilsInvokeMethod () {Ansatt ansatt = ny ansatt (); ReflectionTestUtils.setField (ansatt, "id", 1); ansatte.setName ("Smith, John"); assertTrue (ReflectionTestUtils.invokeMethod (ansatt, "employeeToString") .equals ("id: 1; navn: Smith, John")); }
5. Bruke ReflectionTestUtils å injisere avhengigheter
La oss si at ønsker å skrive en enhetstest for følgende vårkomponent som har et privat felt med @Autowired kommentar:
@Komponent offentlig klasse EmployeeService {@Autowired private HRService hrService; public String findEmployeeStatus (Integer employeeId) {return "Employee" + employeeId + "status:" + hrService.getEmployeeStatus (employeeId); }}
Vi kan nå implementere HRService komponent som nedenfor:
@Komponent offentlig klasse HRService {public String getEmployeeStatus (Integer employeeId) {return "Inactive"; }}
Videre, la oss lage en mock implementering for HRService klasse ved å bruke Mockito. Vi sprøyter denne spotten inn i EmployeeService forekomst, og vi vil bruke den i vår enhetstest:
HRService hrService = mock (HRService.class); når (hrService.getEmployeeStatus (medarbeider.getId ())). deretterReturn ("Aktiv");
Fordi hrService er et privat felt uten en offentlig setter, vil vi bruke ReflectionTestUtils.setField metode for å injisere mocken vi opprettet ovenfor i dette private feltet.
EmployeeService employeeService = ny EmployeeService (); ReflectionTestUtils.setField (medarbeiderservice, "hrService", hrService);
Til slutt vil enhetstesten vår se ut som denne:
@Test offentlig ugyldig nårInjectingMockOfDependency_thenReflectionTestUtilsSetField () {ansatt ansatt = ny ansatt (); ReflectionTestUtils.setField (ansatt, "id", 1); ansatte.setName ("Smith, John"); HRService hrService = mock (HRService.class); når (hrService.getEmployeeStatus (medarbeider.getId ())). deretterReturn ("Aktiv"); EmployeeService employeeService = ny EmployeeService (); // Injiser mock i det private feltet ReflectionTestUtils.setField (medarbeiderservice, "hrService", hrService); assertEquals ("Ansatt" + ansatt.getId () + "status: Aktiv", ansattService.findEmployeeStatus (ansatt.getId ())); }
Vi bør merke oss at denne teknikken er en løsning for det faktum at vi bruker feltinjeksjon i vår bønneklasse. Hvis vi gikk over til injeksjon av konstruktører, ville ikke denne tilnærmingen være nødvendig.
6. Konklusjon
I denne opplæringen viste vi hvordan du bruker ReflectionTestUtils i enhetstesting ved å gå gjennom flere eksempler.
Kodeeksempler, som alltid, kan du finne på Github.