Mockito Mocks in Spring Beans injecteren

1. Overzicht

In dit artikel laten we zien hoe u afhankelijkheidsinjectie kunt gebruiken om Mockito-spotjes in Spring Beans in te voegen voor het testen van eenheden.

In praktijktoepassingen, waar componenten vaak afhankelijk zijn van toegang tot externe systemen, is het belangrijk om een ​​goede testisolatie te bieden, zodat we ons kunnen concentreren op het testen van de functionaliteit van een bepaalde eenheid zonder de hele klassenhiërarchie voor elke test te betrekken.

Het injecteren van een mock is een schone manier om een ​​dergelijk isolement te introduceren.

2. Maven afhankelijkheden

We hebben de volgende Maven-afhankelijkheden nodig voor de unit tests en de mock-objecten:

 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 

We hebben besloten om Spring Boot voor dit voorbeeld te gebruiken, maar de klassieke Spring zal ook prima werken.

3. Het schrijven van de test

3.1. De bedrijfslogica

Laten we eerst een eenvoudige service maken die we gaan testen:

@Service public class NameService {public String getUserName (String id) {return "Echte gebruikersnaam"; }}

En injecteer het in de Gebruikersservice klasse:

@Service openbare klasse UserService {private NameService nameService; @Autowired openbare UserService (NameService nameService) {this.nameService = nameService; } public String getUserName (String id) {return nameService.getUserName (id); }}

Voor deze zelfstudie retourneren de gegeven klassen een enkele naam, ongeacht de opgegeven id. Dit wordt gedaan zodat we niet worden afgeleid door het testen van complexe logica.

We hebben ook een standaard Spring Boot-hoofdklasse nodig om de bonen te scannen en de applicatie te initialiseren:

@SpringBootApplication openbare klasse MocksApplication {openbare statische leegte hoofd (String [] args) {SpringApplication.run (MocksApplication.class, args); }}

3.2. De testen

Laten we nu verder gaan met de testlogica. Allereerst moeten we de toepassingscontext configureren voor de tests:

@Profile ("test") @Configuration openbare klasse NameServiceTestConfiguration {@Bean @Primary openbare NameService nameService () {retourneer Mockito.mock (NameService.class); }}

De @Profiel annotatie vertelt Spring om deze configuratie alleen toe te passen als het "test" -profiel actief is. De @Primair annotatie is er om ervoor te zorgen dat deze instantie wordt gebruikt in plaats van een echte instantie voor automatische bedrading. De methode zelf creëert en retourneert een Mockito-mock van ons Naamservice klasse.

Nu kunnen we de unit-test schrijven:

@ActiveProfiles ("test") @RunWith (SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration (klassen = MocksApplication.class) openbare klasse UserServiceUnitTest {@Autowired private UserService userService; @Autowired private NameService nameService; @Test openbare leegte whenUserIdIsProvided_thenRetrievedNameIsCorrect () {Mockito.when (nameService.getUserName ("SomeId")). ThenReturn ("Mock-gebruikersnaam"); String testName = userService.getUserName ("SomeId"); Assert.assertEquals ("Onechte gebruikersnaam", testnaam); }}

Wij gebruiken de @ActiveProfiles annotatie om het "test" -profiel in te schakelen en de nepconfiguratie te activeren die we eerder hebben geschreven. Daarom maakt Spring autowires een echte instantie van de Gebruikersservice klasse, maar een aanfluiting van de Naamservice klasse. De test zelf is een vrij typische JUnit + Mockito-test. We configureren het gewenste gedrag van de mock, roepen vervolgens de methode aan die we willen testen en beweren dat deze de waarde retourneert die we verwachten.

Het is ook mogelijk (hoewel niet aanbevolen) om het gebruik van omgevingsprofielen in dergelijke tests te vermijden. Verwijder hiervoor het @Profile en @ActiveProfiles annotaties en voeg een @ContextConfiguration (klassen = NameServiceTestConfiguration.class) annotatie bij de UserServiceTest klasse.

4. Conclusie

In deze korte tutorial hebben we laten zien hoe gemakkelijk het is om Mockito-spot in Spring Beans te injecteren.

Zoals gewoonlijk zijn alle codevoorbeelden beschikbaar op GitHub.