From 448d855809aa7380663cc4b2b6f88b23e5eb7bde Mon Sep 17 00:00:00 2001 From: Narendra Pathai Date: Fri, 18 Mar 2016 16:39:45 +0530 Subject: [PATCH] implemented and added test cases for DB dao. Added dependency of Hierarchical junit runner in parent pom --- dao/pom.xml | 8 + .../java/com/iluwatar/dao/DBCustomerDao.java | 114 ++++++++++++-- .../com/iluwatar/dao/DBCustomerDaoTest.java | 149 ++++++++++++++++++ pom.xml | 7 + 4 files changed, 267 insertions(+), 11 deletions(-) create mode 100644 dao/src/test/java/com/iluwatar/dao/DBCustomerDaoTest.java diff --git a/dao/pom.xml b/dao/pom.xml index 3b6fc7d1e..3f22a0cc6 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -44,6 +44,14 @@ log4j log4j + + com.h2database + h2 + + + de.bechte.junit + junit-hierarchicalcontextrunner + diff --git a/dao/src/main/java/com/iluwatar/dao/DBCustomerDao.java b/dao/src/main/java/com/iluwatar/dao/DBCustomerDao.java index fb53c1fed..1b9c4b981 100644 --- a/dao/src/main/java/com/iluwatar/dao/DBCustomerDao.java +++ b/dao/src/main/java/com/iluwatar/dao/DBCustomerDao.java @@ -1,38 +1,130 @@ package com.iluwatar.dao; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.Consumer; import java.util.stream.Stream; +import java.util.stream.StreamSupport; public class DBCustomerDao implements CustomerDao { - @Override - public Stream getAll() { - // TODO Auto-generated method stub - return null; + private String dbUrl; + + public DBCustomerDao(String dbUrl) { + this.dbUrl = dbUrl; } + @Override + public Stream getAll() { + + Connection connection; + try { + connection = getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT * FROM CUSTOMERS"); + ResultSet resultSet = statement.executeQuery(); + return StreamSupport.stream(new Spliterators.AbstractSpliterator(Long.MAX_VALUE, Spliterator.ORDERED) { + + @Override + public boolean tryAdvance(Consumer action) { + try { + if (!resultSet.next()) { + return false; + } + action.accept(createCustomer(resultSet)); + return true; + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + }}, false).onClose(() -> mutedClose(connection)); + } catch (SQLException e) { + e.printStackTrace(); + return null; + } + } + + private void mutedClose(Connection connection) { + try { + connection.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + private Customer createCustomer(ResultSet resultSet) throws SQLException { + return new Customer(resultSet.getInt("ID"), + resultSet.getString("FNAME"), + resultSet.getString("LNAME")); + } + @Override public Customer getById(int id) { - // TODO Auto-generated method stub + try (Connection connection = getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT * FROM CUSTOMERS WHERE ID = ?")) { + statement.setInt(1, id); + ResultSet resultSet = statement.executeQuery(); + if (resultSet.next()) { + return createCustomer(resultSet); + } + } catch (SQLException ex) { + ex.printStackTrace(); + } return null; } @Override public boolean add(Customer customer) { - // TODO Auto-generated method stub - return false; + if (getById(customer.getId()) != null) { + return false; + } + + try (Connection connection = getConnection(); + PreparedStatement statement = connection.prepareStatement("INSERT INTO CUSTOMERS VALUES (?,?,?)")) { + statement.setInt(1, customer.getId()); + statement.setString(2, customer.getFirstName()); + statement.setString(3, customer.getLastName()); + statement.execute(); + return true; + } catch (SQLException ex) { + ex.printStackTrace(); + return false; + } } @Override public boolean update(Customer customer) { - // TODO Auto-generated method stub - return false; + try (Connection connection = getConnection(); + PreparedStatement statement = connection.prepareStatement("UPDATE CUSTOMERS SET FNAME = ?, LNAME = ? WHERE ID = ?")) { + statement.setString(1, customer.getFirstName()); + statement.setString(2, customer.getLastName()); + statement.setInt(3, customer.getId()); + return statement.executeUpdate() > 0; + } catch (SQLException ex) { + ex.printStackTrace(); + return false; + } } @Override public boolean delete(Customer customer) { - // TODO Auto-generated method stub - return false; + try (Connection connection = getConnection(); + PreparedStatement statement = connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) { + statement.setInt(1, customer.getId()); + return statement.executeUpdate() > 0; + } catch (SQLException ex) { + ex.printStackTrace(); + return false; + } } + private Connection getConnection() throws SQLException { + return DriverManager.getConnection(dbUrl); + } } diff --git a/dao/src/test/java/com/iluwatar/dao/DBCustomerDaoTest.java b/dao/src/test/java/com/iluwatar/dao/DBCustomerDaoTest.java new file mode 100644 index 000000000..202140e98 --- /dev/null +++ b/dao/src/test/java/com/iluwatar/dao/DBCustomerDaoTest.java @@ -0,0 +1,149 @@ +package com.iluwatar.dao; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.stream.Stream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import de.bechte.junit.runners.context.HierarchicalContextRunner; + +@RunWith(HierarchicalContextRunner.class) +public class DBCustomerDaoTest { + + private static final String DB_URL = "jdbc:h2:~/dao:customerdb"; + private DBCustomerDao dao; + private Customer existingCustomer = new Customer(1, "Freddy", "Krueger"); + + @Before + public void createSchema() throws SQLException { + try (Connection connection = DriverManager.getConnection(DB_URL); + Statement statement = connection.createStatement()) { + statement.execute("CREATE TABLE CUSTOMERS (ID NUMBER, FNAME VARCHAR(100), LNAME VARCHAR(100))"); + } + } + + @Before + public void setUp() { + dao = new DBCustomerDao(DB_URL); + boolean result = dao.add(existingCustomer); + assumeTrue(result); + } + + public class NonExistantCustomer { + + @Test + public void addingShouldResultInSuccess() { + try (Stream allCustomers = dao.getAll()) { + assumeTrue(allCustomers.count() == 1); + } + + final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund"); + boolean result = dao.add(nonExistingCustomer); + assertTrue(result); + + assertCustomerCountIs(2); + assertEquals(nonExistingCustomer, dao.getById(nonExistingCustomer.getId())); + } + + @Test + public void deletionShouldBeFailureAndNotAffectExistingCustomers() { + final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund"); + boolean result = dao.delete(nonExistingCustomer); + + assertFalse(result); + assertCustomerCountIs(1); + } + + @Test + public void updationShouldBeFailureAndNotAffectExistingCustomers() { + final int nonExistingId = getNonExistingCustomerId(); + final String newFirstname = "Douglas"; + final String newLastname = "MacArthur"; + final Customer customer = new Customer(nonExistingId, newFirstname, newLastname); + boolean result = dao.update(customer); + + assertFalse(result); + assertNull(dao.getById(nonExistingId)); + } + + @Test + public void retrieveShouldReturnNull() { + assertNull(dao.getById(getNonExistingCustomerId())); + } + + } + + public class ExistingCustomer { + + @Test + public void addingShouldResultInFailureAndNotAffectExistingCustomers() { + Customer existingCustomer = new Customer(1, "Freddy", "Krueger"); + + boolean result = dao.add(existingCustomer); + + assertFalse(result); + assertCustomerCountIs(1); + assertEquals(existingCustomer, dao.getById(existingCustomer.getId())); + } + + @Test + public void deletionShouldBeSuccessAndCustomerShouldBeNonAccessible() { + boolean result = dao.delete(existingCustomer); + + assertTrue(result); + assertCustomerCountIs(0); + assertNull(dao.getById(existingCustomer.getId())); + } + + @Test + public void updationShouldBeSuccessAndAccessingTheSameCustomerShouldReturnUpdatedInformation() { + final String newFirstname = "Bernard"; + final String newLastname = "Montgomery"; + final Customer customer = new Customer(existingCustomer.getId(), newFirstname, newLastname); + boolean result = dao.update(customer); + + assertTrue(result); + + final Customer cust = dao.getById(existingCustomer.getId()); + assertEquals(newFirstname, cust.getFirstName()); + assertEquals(newLastname, cust.getLastName()); + } + + } + + @After + public void deleteSchema() throws SQLException { + try (Connection connection = DriverManager.getConnection(DB_URL); + Statement statement = connection.createStatement()) { + statement.execute("DROP TABLE CUSTOMERS"); + } + } + + private void assertCustomerCountIs(int count) { + try (Stream allCustomers = dao.getAll()) { + assertTrue(allCustomers.count() == count); + } + } + + + /** + * An arbitrary number which does not correspond to an active Customer id. + * + * @return an int of a customer id which doesn't exist + */ + private int getNonExistingCustomerId() { + return 999; + } +} diff --git a/pom.xml b/pom.xml index 555844660..524a0261b 100644 --- a/pom.xml +++ b/pom.xml @@ -50,6 +50,7 @@ 19.0 1.15.1 1.10.19 + 4.12.1 abstract-factory @@ -195,6 +196,12 @@ ${systemrules.version} test + + de.bechte.junit + junit-hierarchicalcontextrunner + ${hierarchical-junit-runner-version} + test +