diff --git a/persistence-modules/core-java-persistence-4/pom.xml b/persistence-modules/core-java-persistence-4/pom.xml index 801ed4bfa137..264183f23cb4 100644 --- a/persistence-modules/core-java-persistence-4/pom.xml +++ b/persistence-modules/core-java-persistence-4/pom.xml @@ -47,6 +47,13 @@ spring-boot-starter ${springframework.boot.spring-boot-starter.version} + + + org.mockito + mockito-junit-jupiter + 5.16.0 + test + diff --git a/persistence-modules/core-java-persistence-4/src/main/java/com/baeldung/jdbc/mocking/Customer.java b/persistence-modules/core-java-persistence-4/src/main/java/com/baeldung/jdbc/mocking/Customer.java new file mode 100644 index 000000000000..55bda68b3d68 --- /dev/null +++ b/persistence-modules/core-java-persistence-4/src/main/java/com/baeldung/jdbc/mocking/Customer.java @@ -0,0 +1,8 @@ +package com.baeldung.jdbc.mocking; + +public record Customer(int id, String name, Status status) { + + public enum Status { + ACTIVE, LOYAL, INACTIVE + } +} \ No newline at end of file diff --git a/persistence-modules/core-java-persistence-4/src/main/java/com/baeldung/jdbc/mocking/CustomersService.java b/persistence-modules/core-java-persistence-4/src/main/java/com/baeldung/jdbc/mocking/CustomersService.java new file mode 100644 index 000000000000..8906bf78cd5d --- /dev/null +++ b/persistence-modules/core-java-persistence-4/src/main/java/com/baeldung/jdbc/mocking/CustomersService.java @@ -0,0 +1,45 @@ +package com.baeldung.jdbc.mocking; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +import javax.sql.DataSource; + +import com.baeldung.jdbc.mocking.Customer.Status; + +public class CustomersService { + + private final DataSource dataSource; + + public CustomersService(DataSource dataSource) { + this.dataSource = dataSource; + } + + public List customersEligibleForOffers() throws SQLException { + try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) { + ResultSet resultSet = stmt.executeQuery("SELECT * FROM customers"); + List customers = new ArrayList<>(); + + while (resultSet.next()) { + Customer customer = mapCustomer(resultSet); + if (customer.status() == Status.ACTIVE || customer.status() == Status.LOYAL) { + customers.add(customer); + } + } + return customers; + } + } + + private Customer mapCustomer(ResultSet resultSet) throws SQLException { + return new Customer( + resultSet.getInt("id"), + resultSet.getString("name"), + Status.valueOf(resultSet.getString("status")) + ); + } + +} \ No newline at end of file diff --git a/persistence-modules/core-java-persistence-4/src/main/java/com/baeldung/jdbc/mocking/v2/AllCustomers.java b/persistence-modules/core-java-persistence-4/src/main/java/com/baeldung/jdbc/mocking/v2/AllCustomers.java new file mode 100644 index 000000000000..022b7cabe78c --- /dev/null +++ b/persistence-modules/core-java-persistence-4/src/main/java/com/baeldung/jdbc/mocking/v2/AllCustomers.java @@ -0,0 +1,41 @@ +package com.baeldung.jdbc.mocking.v2; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +import javax.sql.DataSource; + +import com.baeldung.jdbc.mocking.Customer; + +public class AllCustomers implements Supplier> { + + private final DataSource dataSource; + + @Override + public List get() { + try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) { + ResultSet resultSet = stmt.executeQuery("SELECT * FROM customers"); + List customers = new ArrayList<>(); + while (resultSet.next()) { + customers.add(mapCustomer(resultSet)); + } + return customers; + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + public AllCustomers(DataSource dataSource) { + this.dataSource = dataSource; + } + + private Customer mapCustomer(ResultSet resultSet) throws SQLException { + return new Customer(resultSet.getInt("id"), resultSet.getString("name"), Customer.Status.valueOf(resultSet.getString("status"))); + } + +} \ No newline at end of file diff --git a/persistence-modules/core-java-persistence-4/src/main/java/com/baeldung/jdbc/mocking/v2/CustomersServiceV2.java b/persistence-modules/core-java-persistence-4/src/main/java/com/baeldung/jdbc/mocking/v2/CustomersServiceV2.java new file mode 100644 index 000000000000..8ccc7b06cdc1 --- /dev/null +++ b/persistence-modules/core-java-persistence-4/src/main/java/com/baeldung/jdbc/mocking/v2/CustomersServiceV2.java @@ -0,0 +1,24 @@ +package com.baeldung.jdbc.mocking.v2; + +import java.util.List; +import java.util.function.Supplier; + +import com.baeldung.jdbc.mocking.Customer; +import com.baeldung.jdbc.mocking.Customer.Status; + +public class CustomersServiceV2 { + + private final Supplier> findAllCustomers; + + public List customersEligibleForOffers() { + return findAllCustomers.get() + .stream() + .filter(customer -> customer.status() == Status.ACTIVE || customer.status() == Status.LOYAL) + .toList(); + } + + public CustomersServiceV2(Supplier> findAllCustomers) { + this.findAllCustomers = findAllCustomers; + } + +} \ No newline at end of file diff --git a/persistence-modules/core-java-persistence-4/src/test/java/com/baeldung/jdbc/mocking/JdbcMockingIntegrationTest.java b/persistence-modules/core-java-persistence-4/src/test/java/com/baeldung/jdbc/mocking/JdbcMockingIntegrationTest.java new file mode 100644 index 000000000000..e8c48827ff02 --- /dev/null +++ b/persistence-modules/core-java-persistence-4/src/test/java/com/baeldung/jdbc/mocking/JdbcMockingIntegrationTest.java @@ -0,0 +1,36 @@ +package com.baeldung.jdbc.mocking; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +import java.sql.SQLException; +import java.util.List; + +import org.h2.jdbcx.JdbcDataSource; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import com.baeldung.jdbc.mocking.Customer.Status; + +class JdbcMockingIntegrationTest { + + private static JdbcDataSource dataSource; + + @BeforeAll + static void setUp() { + dataSource = new JdbcDataSource(); + dataSource.setURL("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;INIT=RUNSCRIPT FROM 'classpath:data.sql'"); + dataSource.setUser("sa"); + dataSource.setPassword(""); + } + + @Test + void whenFetchingCustomersEligibleForOffers_thenTheyHaveActiveOrLoyalStatus() throws SQLException { + CustomersService customersService = new CustomersService(dataSource); + + List customers = customersService.customersEligibleForOffers(); + + assertThat(customers).extracting(Customer::status) + .containsOnly(Status.ACTIVE, Status.LOYAL); + } + +} \ No newline at end of file diff --git a/persistence-modules/core-java-persistence-4/src/test/java/com/baeldung/jdbc/mocking/JdbcMockingUnitTest.java b/persistence-modules/core-java-persistence-4/src/test/java/com/baeldung/jdbc/mocking/JdbcMockingUnitTest.java new file mode 100644 index 000000000000..b57ca00a1ecf --- /dev/null +++ b/persistence-modules/core-java-persistence-4/src/test/java/com/baeldung/jdbc/mocking/JdbcMockingUnitTest.java @@ -0,0 +1,76 @@ +package com.baeldung.jdbc.mocking; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.mockito.Mockito.when; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.List; + +import javax.sql.DataSource; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.baeldung.jdbc.mocking.Customer.Status; +import com.baeldung.jdbc.mocking.v2.CustomersServiceV2; + +@ExtendWith(MockitoExtension.class) +class JdbcMockingUnitTest { + + @Mock + DataSource dataSource; + @Mock + Connection conn; + @Mock + Statement stmt; + @Mock + ResultSet resultSet; + + @Test + void whenFetchingEligibleCustomers_thenTheyHaveCorrectStatus() throws Exception { + //given + CustomersService customersService = new CustomersService(dataSource); + + when(dataSource.getConnection()) + .thenReturn(conn); + when(conn.createStatement()) + .thenReturn(stmt); + when(stmt.executeQuery("SELECT * FROM customers")) + .thenReturn(resultSet); + + when(resultSet.next()) + .thenReturn(true, true, true, false); + when(resultSet.getInt("id")) + .thenReturn(1, 2, 3); + when(resultSet.getString("name")) + .thenReturn("Alice", "Bob", "John"); + when(resultSet.getString("status")) + .thenReturn("LOYAL", "ACTIVE", "INACTIVE"); + + // when + List eligibleCustomers = customersService.customersEligibleForOffers(); + + // then + assertThat(eligibleCustomers).containsExactlyInAnyOrder(new Customer(1, "Alice", Status.LOYAL), new Customer(2, "Bob", Status.ACTIVE)); + } + + @Test + void whenFetchingEligibleCustomersFromV2_thenTheyHaveCorrectStatus() { + // given + List allCustomers = List.of(new Customer(1, "Alice", Status.LOYAL), new Customer(2, "Bob", Status.ACTIVE), + new Customer(3, "John", Status.INACTIVE)); + + CustomersServiceV2 service = new CustomersServiceV2(() -> allCustomers); + + // when + List eligibleCustomers = service.customersEligibleForOffers(); + + // then + assertThat(eligibleCustomers).containsExactlyInAnyOrder(new Customer(1, "Alice", Status.LOYAL), new Customer(2, "Bob", Status.ACTIVE)); + } + +} \ No newline at end of file diff --git a/persistence-modules/core-java-persistence-4/src/test/resources/data.sql b/persistence-modules/core-java-persistence-4/src/test/resources/data.sql new file mode 100644 index 000000000000..774a0b55fb6c --- /dev/null +++ b/persistence-modules/core-java-persistence-4/src/test/resources/data.sql @@ -0,0 +1,4 @@ +create table customers (id int primary key, name varchar(255), status varchar(255)); +insert into customers (id, name, status) values (1, 'Alice', 'LOYAL'); +insert into customers (id, name, status) values (2, 'Bob', 'ACTIVE'); +insert into customers (id, name, status) values (3, 'Charlie', 'INACTIVE'); \ No newline at end of file