Injisere Mockito Mocks i vårbønner
1. Oversikt
I denne artikkelen viser vi hvordan du bruker avhengighetsinjeksjon for å sette inn Mockito-mocks i Spring Beans for enhetstesting.
I virkelige applikasjoner, der komponenter ofte er avhengige av tilgang til eksterne systemer, er det viktig å sørge for riktig testisolasjon slik at vi kan fokusere på å teste funksjonaliteten til en gitt enhet uten å måtte involvere hele klassehierarkiet for hver test.
Å injisere en mock er en ren måte å innføre en slik isolasjon på.
2. Maven-avhengigheter
Vi trenger følgende Maven-avhengigheter for enhetstestene og de spotte objektene:
org.springframework.boot spring-boot-starter 2.2.2.RELEASE org.springframework.boot spring-boot-starter-test 2.2.2.RELEASE test org.mockito mockito-core 2.21.0
Vi bestemte oss for å bruke Spring Boot for dette eksemplet, men classic Spring vil også fungere bra.
3. Skrive testen
3.1. Forretningslogikken
La oss først lage en enkel tjeneste som vi skal teste:
@Service offentlig klasse NameService {public String getUserName (String id) {return "Real user name"; }}
Og injiser den i UserService klasse:
@Service offentlig klasse UserService {private NameService nameService; @Autowired public UserService (NameService nameService) {this.nameService = nameService; } public String getUserName (String id) {return nameService.getUserName (id); }}
For denne opplæringen returnerer de gitte klassene et enkelt navn, uavhengig av ID-en. Dette gjøres slik at vi ikke blir distrahert av å teste noen kompleks logikk.
Vi trenger også en standard Spring Boot-hovedklasse for å skanne bønnene og initialisere applikasjonen:
@SpringBootApplication public class MocksApplication {public static void main (String [] args) {SpringApplication.run (MocksApplication.class, args); }}
3.2. Testene
La oss nå gå videre til testlogikken. Først og fremst må vi konfigurere applikasjonskontekst for testene:
@Profile ("test") @Configuration public class NameServiceTestConfiguration {@Bean @Primary public NameService nameService () {return Mockito.mock (NameService.class); }}
De @Profil merknader forteller Spring å bruke denne konfigurasjonen bare når "test" -profilen er aktiv. De @Hoved merknader er der for å sikre at denne forekomsten blir brukt i stedet for en ekte for autokabel. Selve metoden skaper og returnerer en Mockito-mock av oss NameService klasse.
Nå kan vi skrive enhetstesten:
@ActiveProfiles ("test") @RunWith (SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration (classes = MocksApplication.class) public class UserServiceUnitTest {@Autowired private UserService userService; @Autowired private NameService nameService; @Test offentlig ugyldig nårUserIdIsProvided_thenRetrievedNameIsCorrect () {Mockito.when (nameService.getUserName ("SomeId")). ThenReturn ("Mock user name"); Streng testnavn = userService.getUserName ("SomeId"); Assert.assertEquals ("Mock user name", testName); }}
Vi bruker @ActiveProfiles kommentar for å aktivere “test” -profilen og aktivere mock-konfigurasjonen vi skrev tidligere. På grunn av dette, Spring autowires en reell forekomst av UserService klasse, men en latterliggjøring av NameService klasse. Selve testen er en ganske typisk JUnit + Mockito-test. Vi konfigurerer mockens ønskede oppførsel, og kaller deretter metoden som vi vil teste, og hevder at den returnerer verdien vi forventer.
Det er også mulig (men ikke anbefalt) å unngå å bruke miljøprofiler i slike tester. Fjern dette for å gjøre det @Profile og @ActiveProfiles merknader og legg til en @ContextConfiguration (klasser = NameServiceTestConfiguration.class) kommentar til UserServiceTest klasse.
4. Konklusjon
I denne raske opplæringen viste vi hvor enkelt det er å injisere Mockito-mocks i Spring Beans.
Som vanlig er alle kodeeksemplene tilgjengelig på GitHub.