Iniezione di Mockito Mocks in Spring Beans

1. Panoramica

In questo articolo mostreremo come utilizzare l'inserimento delle dipendenze per inserire mock Mockito in Spring Beans per test unitari.

Nelle applicazioni del mondo reale, in cui i componenti spesso dipendono dall'accesso a sistemi esterni, è importante fornire un adeguato isolamento dei test in modo che possiamo concentrarci sul test della funzionalità di una data unità senza dover coinvolgere l'intera gerarchia di classi per ogni test.

Iniettare una finta è un modo pulito per introdurre tale isolamento.

2. Dipendenze di Maven

Abbiamo bisogno delle seguenti dipendenze Maven per gli unit test e gli oggetti fittizi:

 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 

Abbiamo deciso di utilizzare Spring Boot per questo esempio, ma anche Spring classico funzionerà bene.

3. Scrittura del test

3.1. La logica aziendale

Per prima cosa, creiamo un semplice servizio che testeremo:

@Service public class NameService { public String getUserName(String id) { return "Real user name"; } }

E iniettalo nella classe UserService :

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

Per questo tutorial, le classi fornite restituiscono un unico nome indipendentemente dall'id fornito. Questo viene fatto in modo da non farci distrarre testando alcuna logica complessa.

Avremo anche bisogno di una classe principale Spring Boot standard per scansionare i bean e inizializzare l'applicazione:

@SpringBootApplication public class MocksApplication { public static void main(String[] args) { SpringApplication.run(MocksApplication.class, args); } }

3.2. I test

Ora passiamo alla logica del test. Prima di tutto, dobbiamo configurare il contesto dell'applicazione per i test:

@Profile("test") @Configuration public class NameServiceTestConfiguration { @Bean @Primary public NameService nameService() { return Mockito.mock(NameService.class); } }

L' annotazione @Profile dice a Spring di applicare questa configurazione solo quando il profilo "test" è attivo. L' annotazione @Primary serve per assicurarsi che questa istanza venga utilizzata al posto di una reale per il cablaggio automatico. Il metodo stesso crea e restituisce una simulazione Mockito della nostra classe NameService .

Ora possiamo scrivere lo unit test:

@ActiveProfiles("test") @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MocksApplication.class) public class UserServiceUnitTest { @Autowired private UserService userService; @Autowired private NameService nameService; @Test public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() { Mockito.when(nameService.getUserName("SomeId")).thenReturn("Mock user name"); String testName = userService.getUserName("SomeId"); Assert.assertEquals("Mock user name", testName); } }

Usiamo l' annotazione @ActiveProfiles per abilitare il profilo "test" e attivare la configurazione fittizia che abbiamo scritto in precedenza. Per questo motivo, Spring autowires un'istanza reale della classe UserService , ma una simulazione della classe NameService . Il test stesso è un test JUnit + Mockito abbastanza tipico. Configuriamo il comportamento desiderato del mock, quindi chiamiamo il metodo che vogliamo testare e affermiamo che restituisce il valore che ci aspettiamo.

È anche possibile (sebbene non consigliato) evitare di utilizzare i profili di ambiente in tali test. Per fare ciò, rimuovere le annotazioni @Profile e @ActiveProfiles e aggiungere un'annotazione @ContextConfiguration (classes = NameServiceTestConfiguration.class) alla classe UserServiceTest .

4. Conclusione

In questo rapido tutorial, abbiamo mostrato quanto sia facile iniettare mock Mockito in Spring Beans.

Come al solito, tutti gli esempi di codice sono disponibili su GitHub.