From 3f96ca32f69a0f78d7a0eed5920eee8fe49f2021 Mon Sep 17 00:00:00 2001 From: Mateusz Szablak Date: Mon, 17 Nov 2025 14:45:00 +0100 Subject: [PATCH] BAEL-9322 What is @MockitoSpyBean in Spring --- spring-boot-modules/pom.xml | 1 + .../spring-boot-testing-5/pom.xml | 33 +++++++++++++ .../mockitospytest/ExternalAlertService.java | 6 +++ .../mockitospytest/NotificationService.java | 18 +++++++ .../com/baeldung/mockitospytest/Order.java | 49 +++++++++++++++++++ .../mockitospytest/OrderRepository.java | 19 +++++++ .../baeldung/mockitospytest/OrderService.java | 25 ++++++++++ .../mockitospytest/SpyTestApplication.java | 13 +++++ .../mockitospytest/OrderServiceUnitTest.java | 30 ++++++++++++ 9 files changed, 194 insertions(+) create mode 100644 spring-boot-modules/spring-boot-testing-5/pom.xml create mode 100644 spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/ExternalAlertService.java create mode 100644 spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/NotificationService.java create mode 100644 spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/Order.java create mode 100644 spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/OrderRepository.java create mode 100644 spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/OrderService.java create mode 100644 spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/SpyTestApplication.java create mode 100644 spring-boot-modules/spring-boot-testing-5/src/test/java/com/baeldung/mockitospytest/OrderServiceUnitTest.java diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index 655bcb67cf26..3773c375899a 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -94,6 +94,7 @@ spring-boot-testing-2 spring-boot-testing-3 spring-boot-testing-4 + spring-boot-testing-5 spring-boot-testing-spock spring-boot-vue spring-boot-actuator diff --git a/spring-boot-modules/spring-boot-testing-5/pom.xml b/spring-boot-modules/spring-boot-testing-5/pom.xml new file mode 100644 index 000000000000..f77361a67373 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-5/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + + + spring-boot-testing-5 + + + 21 + 5.12.2 + 1.5.20 + 3.5.7 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-test + test + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/ExternalAlertService.java b/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/ExternalAlertService.java new file mode 100644 index 000000000000..f79572b1de4e --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/ExternalAlertService.java @@ -0,0 +1,6 @@ +package com.baeldung.mockitospytest; + +public interface ExternalAlertService { + public boolean alert(Order order); + +} diff --git a/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/NotificationService.java b/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/NotificationService.java new file mode 100644 index 000000000000..7f6ea55c4e9e --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/NotificationService.java @@ -0,0 +1,18 @@ +package com.baeldung.mockitospytest; + +import org.springframework.stereotype.Component; + +@Component +public class NotificationService { + + private ExternalAlertService externalAlertService; + + public void notify(Order order) { + System.out.println(order); + } + + public boolean raiseAlert(Order order) { + return externalAlertService.alert(order); + } + +} diff --git a/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/Order.java b/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/Order.java new file mode 100644 index 000000000000..54b0a351cc02 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/Order.java @@ -0,0 +1,49 @@ +package com.baeldung.mockitospytest; + +import java.util.UUID; + +public class Order { + + private UUID id; + + private String name; + + private OrderType orderType; + + private double orderQuantity; + + private String address; + + public Order(UUID id, String name, double orderQuantity, String address) { + this.id = id; + this.name = name; + this.orderQuantity = orderQuantity; + this.address = address; + } + + public enum OrderType { + INDIVIDUAL, BULK; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + + public double getOrderQuantity() { + return orderQuantity; + } + + public String getAddress() { + return address; + } +} + + diff --git a/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/OrderRepository.java b/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/OrderRepository.java new file mode 100644 index 000000000000..a7279f03de26 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/OrderRepository.java @@ -0,0 +1,19 @@ +package com.baeldung.mockitospytest; + +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.UUID; + +@Component +public class OrderRepository { + + public static final HashMap orders = new HashMap<>(); + + public Order save(Order order) { + UUID orderId = UUID.randomUUID(); + order.setId(orderId); + orders.put(UUID.randomUUID(), order); + return order; + } +} diff --git a/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/OrderService.java b/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/OrderService.java new file mode 100644 index 000000000000..0d5dfb1d12a0 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/OrderService.java @@ -0,0 +1,25 @@ +package com.baeldung.mockitospytest; + +import org.springframework.stereotype.Service; + +@Service +public class OrderService { + + public final OrderRepository orderRepository; + + public final NotificationService notificationService; + + public OrderService(OrderRepository orderRepository, NotificationService notificationService) { + this.orderRepository = orderRepository; + this.notificationService = notificationService; + } + + public Order save(Order order) { + order = orderRepository.save(order); + notificationService.notify(order); + if (!notificationService.raiseAlert(order)) { + throw new RuntimeException("Alert not raised"); + } + return order; + } +} diff --git a/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/SpyTestApplication.java b/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/SpyTestApplication.java new file mode 100644 index 000000000000..5fb0404a2ce2 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-5/src/main/java/com/baeldung/mockitospytest/SpyTestApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.mockitospytest; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpyTestApplication { + + public static void main(String[] args) { + SpringApplication.run(SpyTestApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-testing-5/src/test/java/com/baeldung/mockitospytest/OrderServiceUnitTest.java b/spring-boot-modules/spring-boot-testing-5/src/test/java/com/baeldung/mockitospytest/OrderServiceUnitTest.java new file mode 100644 index 000000000000..954e8bbac1ea --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-5/src/test/java/com/baeldung/mockitospytest/OrderServiceUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.mockitospytest; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; + +@SpringBootTest +class OrderServiceUnitTest { + @MockitoSpyBean + NotificationService notificationService; + @MockitoSpyBean + OrderService orderService; + + @Test + void givenNotificationServiceIsUsingSpyBean_whenOrderServiceIsCalled_thenNotificationServiceSpyBeanShouldBeInvoked() { + Order orderInput = new Order(null, "Test", 1.0, "17 St Andrews Croft, Leeds ,LS17 7TP"); + doReturn(true).when(notificationService) + .raiseAlert(any(Order.class)); + Order order = orderService.save(orderInput); + Assertions.assertNotNull(order); + Assertions.assertNotNull(order.getId()); + verify(notificationService).notify(any(Order.class)); + } + +} \ No newline at end of file