Injizieren von Mockito-Mocks in Spring Beans

Injizieren von Mockito Mocks in Frühlingsbohnen

1. Überblick

Dieser Artikel zeigt, wie Sie mithilfe der Abhängigkeitsinjektion Mockito-Mocks in Spring Beans für Komponententests einfügen können.

In realen Anwendungen, in denen Komponenten häufig vom Zugriff auf externe Systeme abhängen, ist es wichtig, eine ordnungsgemäße Testisolierung bereitzustellen, damit wir uns auf das Testen der Funktionalität einer bestimmten Einheit konzentrieren können, ohne die gesamte Klassenhierarchie für jeden Test einbeziehen zu müssen.

Das Injizieren eines Mocks ist ein sauberer Weg, um eine solche Isolation einzuführen.

2. Maven-Abhängigkeiten

Die folgenden Maven-Abhängigkeiten sind für die Unit-Tests und die Mock-Objekte erforderlich:


    org.springframework.boot
    spring-boot-starter
    1.3.1.RELEASE


    org.springframework.boot
    spring-boot-starter-test
    1.3.1.RELEASE
    test


    org.mockito
    mockito-core
    2.21.0

Wir haben uns für Spring Boot entschieden, aber auch für Classic Spring.

3. Test schreiben

3.1. Die Geschäftslogik

Zuerst schreiben wir die Geschäftslogik, die getestet werden soll:

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

Die KlasseNameServicewird eingefügt in:

@Service
public class UserService {

    private NameService nameService;

    @Autowired
    public UserService(NameService nameService) {
        this.nameService = nameService;
    }

    public String getUserName(String id) {
        return nameService.getUserName(id);
    }
}

In diesem Lernprogramm geben die angegebenen Klassen unabhängig von der angegebenen ID einen einzelnen Namen zurück. Dies geschieht, damit wir nicht durch das Testen komplexer Logik abgelenkt werden.

Wir benötigen außerdem eine Standard-Spring Boot-Hauptklasse, um die Beans zu scannen und die Anwendung zu initialisieren:

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

3.2. Die Tests

Fahren wir nun mit der Testlogik fort. Zunächst müssen wir den Anwendungskontext für die Tests konfigurieren:

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

Die Annotation@Profileweist Spring an, diese Konfiguration nur anzuwenden, wenn das Testprofil aktiv ist. Die Annotation@Primarydient dazu, sicherzustellen, dass diese Instanz anstelle einer echten Instanz für die automatische Verdrahtung verwendet wird. Die Methode selbst erstellt und gibt einen Mockito-Mock unsererNameService-Klasse zurück.

Jetzt können wir den Komponententest schreiben:

@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);
    }
}

Wir verwenden die Annotation@ActiveProfiles, um das Testprofil zu aktivieren und die zuvor geschriebene Scheinkonfiguration zu aktivieren. Aus diesem Grund verdrahtet Spring automatisch eine reale Instanz derUserService-Klasse, aber ein Modell derNameService-Klasse. Der Test selbst ist ein ziemlich typischer JUnit + Mockito-Test. Wir konfigurieren das gewünschte Verhalten des Mocks, rufen dann die zu testende Methode auf und bestätigen, dass sie den erwarteten Wert zurückgibt.

Es ist auch möglich (obwohl nicht empfohlen), die Verwendung von Umgebungsprofilen bei solchen Tests zu vermeiden. Entfernen Sie dazu die Annotationen von@Profile and @ActiveProfilesund fügen Sie der Klasse vonUserServiceTesteine Annotation von@ContextConfiguration(classes = NameServiceTestConfiguration.class)hinzu.

4. Fazit

Das Tutorial zeigte, wie man Mockito-Mocks in Spring Beans injiziert. Die Implementierung finden Sie inexample GitHub project.