Skip to content

Commit 448d855

Browse files
committed
implemented and added test cases for DB dao. Added dependency of Hierarchical junit runner in parent pom
1 parent f6a20c7 commit 448d855

File tree

4 files changed

+265
-9
lines changed

4 files changed

+265
-9
lines changed

dao/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@
4444
<groupId>log4j</groupId>
4545
<artifactId>log4j</artifactId>
4646
</dependency>
47+
<dependency>
48+
<groupId>com.h2database</groupId>
49+
<artifactId>h2</artifactId>
50+
</dependency>
51+
<dependency>
52+
<groupId>de.bechte.junit</groupId>
53+
<artifactId>junit-hierarchicalcontextrunner</artifactId>
54+
</dependency>
4755
</dependencies>
4856

4957
<build>
Lines changed: 101 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,130 @@
11
package com.iluwatar.dao;
22

3+
import java.sql.Connection;
4+
import java.sql.DriverManager;
5+
import java.sql.PreparedStatement;
6+
import java.sql.ResultSet;
7+
import java.sql.SQLException;
8+
import java.util.Spliterator;
9+
import java.util.Spliterators;
10+
import java.util.function.Consumer;
311
import java.util.stream.Stream;
12+
import java.util.stream.StreamSupport;
413

514
public class DBCustomerDao implements CustomerDao {
615

16+
private String dbUrl;
17+
18+
public DBCustomerDao(String dbUrl) {
19+
this.dbUrl = dbUrl;
20+
}
21+
722
@Override
823
public Stream<Customer> getAll() {
9-
// TODO Auto-generated method stub
10-
return null;
24+
25+
Connection connection;
26+
try {
27+
connection = getConnection();
28+
PreparedStatement statement = connection.prepareStatement("SELECT * FROM CUSTOMERS");
29+
ResultSet resultSet = statement.executeQuery();
30+
return StreamSupport.stream(new Spliterators.AbstractSpliterator<Customer>(Long.MAX_VALUE, Spliterator.ORDERED) {
31+
32+
@Override
33+
public boolean tryAdvance(Consumer<? super Customer> action) {
34+
try {
35+
if (!resultSet.next()) {
36+
return false;
37+
}
38+
action.accept(createCustomer(resultSet));
39+
return true;
40+
} catch (SQLException e) {
41+
e.printStackTrace();
42+
return false;
43+
}
44+
45+
}}, false).onClose(() -> mutedClose(connection));
46+
} catch (SQLException e) {
47+
e.printStackTrace();
48+
return null;
49+
}
50+
}
51+
52+
private void mutedClose(Connection connection) {
53+
try {
54+
connection.close();
55+
} catch (SQLException e) {
56+
e.printStackTrace();
57+
}
1158
}
1259

60+
private Customer createCustomer(ResultSet resultSet) throws SQLException {
61+
return new Customer(resultSet.getInt("ID"),
62+
resultSet.getString("FNAME"),
63+
resultSet.getString("LNAME"));
64+
}
65+
1366
@Override
1467
public Customer getById(int id) {
15-
// TODO Auto-generated method stub
68+
try (Connection connection = getConnection();
69+
PreparedStatement statement = connection.prepareStatement("SELECT * FROM CUSTOMERS WHERE ID = ?")) {
70+
statement.setInt(1, id);
71+
ResultSet resultSet = statement.executeQuery();
72+
if (resultSet.next()) {
73+
return createCustomer(resultSet);
74+
}
75+
} catch (SQLException ex) {
76+
ex.printStackTrace();
77+
}
1678
return null;
1779
}
1880

1981
@Override
2082
public boolean add(Customer customer) {
21-
// TODO Auto-generated method stub
22-
return false;
83+
if (getById(customer.getId()) != null) {
84+
return false;
85+
}
86+
87+
try (Connection connection = getConnection();
88+
PreparedStatement statement = connection.prepareStatement("INSERT INTO CUSTOMERS VALUES (?,?,?)")) {
89+
statement.setInt(1, customer.getId());
90+
statement.setString(2, customer.getFirstName());
91+
statement.setString(3, customer.getLastName());
92+
statement.execute();
93+
return true;
94+
} catch (SQLException ex) {
95+
ex.printStackTrace();
96+
return false;
97+
}
2398
}
2499

25100
@Override
26101
public boolean update(Customer customer) {
27-
// TODO Auto-generated method stub
28-
return false;
102+
try (Connection connection = getConnection();
103+
PreparedStatement statement = connection.prepareStatement("UPDATE CUSTOMERS SET FNAME = ?, LNAME = ? WHERE ID = ?")) {
104+
statement.setString(1, customer.getFirstName());
105+
statement.setString(2, customer.getLastName());
106+
statement.setInt(3, customer.getId());
107+
return statement.executeUpdate() > 0;
108+
} catch (SQLException ex) {
109+
ex.printStackTrace();
110+
return false;
111+
}
29112
}
30113

31114
@Override
32115
public boolean delete(Customer customer) {
33-
// TODO Auto-generated method stub
34-
return false;
116+
try (Connection connection = getConnection();
117+
PreparedStatement statement = connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) {
118+
statement.setInt(1, customer.getId());
119+
return statement.executeUpdate() > 0;
120+
} catch (SQLException ex) {
121+
ex.printStackTrace();
122+
return false;
123+
}
35124
}
36125

126+
private Connection getConnection() throws SQLException {
127+
return DriverManager.getConnection(dbUrl);
128+
}
37129

38130
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package com.iluwatar.dao;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.assertFalse;
5+
import static org.junit.Assert.assertNull;
6+
import static org.junit.Assert.assertTrue;
7+
import static org.junit.Assume.assumeTrue;
8+
9+
import java.sql.Connection;
10+
import java.sql.DriverManager;
11+
import java.sql.SQLException;
12+
import java.sql.Statement;
13+
import java.util.stream.Stream;
14+
15+
import org.junit.After;
16+
import org.junit.Before;
17+
import org.junit.Test;
18+
import org.junit.runner.RunWith;
19+
20+
import de.bechte.junit.runners.context.HierarchicalContextRunner;
21+
22+
@RunWith(HierarchicalContextRunner.class)
23+
public class DBCustomerDaoTest {
24+
25+
private static final String DB_URL = "jdbc:h2:~/dao:customerdb";
26+
private DBCustomerDao dao;
27+
private Customer existingCustomer = new Customer(1, "Freddy", "Krueger");
28+
29+
@Before
30+
public void createSchema() throws SQLException {
31+
try (Connection connection = DriverManager.getConnection(DB_URL);
32+
Statement statement = connection.createStatement()) {
33+
statement.execute("CREATE TABLE CUSTOMERS (ID NUMBER, FNAME VARCHAR(100), LNAME VARCHAR(100))");
34+
}
35+
}
36+
37+
@Before
38+
public void setUp() {
39+
dao = new DBCustomerDao(DB_URL);
40+
boolean result = dao.add(existingCustomer);
41+
assumeTrue(result);
42+
}
43+
44+
public class NonExistantCustomer {
45+
46+
@Test
47+
public void addingShouldResultInSuccess() {
48+
try (Stream<Customer> allCustomers = dao.getAll()) {
49+
assumeTrue(allCustomers.count() == 1);
50+
}
51+
52+
final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
53+
boolean result = dao.add(nonExistingCustomer);
54+
assertTrue(result);
55+
56+
assertCustomerCountIs(2);
57+
assertEquals(nonExistingCustomer, dao.getById(nonExistingCustomer.getId()));
58+
}
59+
60+
@Test
61+
public void deletionShouldBeFailureAndNotAffectExistingCustomers() {
62+
final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund");
63+
boolean result = dao.delete(nonExistingCustomer);
64+
65+
assertFalse(result);
66+
assertCustomerCountIs(1);
67+
}
68+
69+
@Test
70+
public void updationShouldBeFailureAndNotAffectExistingCustomers() {
71+
final int nonExistingId = getNonExistingCustomerId();
72+
final String newFirstname = "Douglas";
73+
final String newLastname = "MacArthur";
74+
final Customer customer = new Customer(nonExistingId, newFirstname, newLastname);
75+
boolean result = dao.update(customer);
76+
77+
assertFalse(result);
78+
assertNull(dao.getById(nonExistingId));
79+
}
80+
81+
@Test
82+
public void retrieveShouldReturnNull() {
83+
assertNull(dao.getById(getNonExistingCustomerId()));
84+
}
85+
86+
}
87+
88+
public class ExistingCustomer {
89+
90+
@Test
91+
public void addingShouldResultInFailureAndNotAffectExistingCustomers() {
92+
Customer existingCustomer = new Customer(1, "Freddy", "Krueger");
93+
94+
boolean result = dao.add(existingCustomer);
95+
96+
assertFalse(result);
97+
assertCustomerCountIs(1);
98+
assertEquals(existingCustomer, dao.getById(existingCustomer.getId()));
99+
}
100+
101+
@Test
102+
public void deletionShouldBeSuccessAndCustomerShouldBeNonAccessible() {
103+
boolean result = dao.delete(existingCustomer);
104+
105+
assertTrue(result);
106+
assertCustomerCountIs(0);
107+
assertNull(dao.getById(existingCustomer.getId()));
108+
}
109+
110+
@Test
111+
public void updationShouldBeSuccessAndAccessingTheSameCustomerShouldReturnUpdatedInformation() {
112+
final String newFirstname = "Bernard";
113+
final String newLastname = "Montgomery";
114+
final Customer customer = new Customer(existingCustomer.getId(), newFirstname, newLastname);
115+
boolean result = dao.update(customer);
116+
117+
assertTrue(result);
118+
119+
final Customer cust = dao.getById(existingCustomer.getId());
120+
assertEquals(newFirstname, cust.getFirstName());
121+
assertEquals(newLastname, cust.getLastName());
122+
}
123+
124+
}
125+
126+
@After
127+
public void deleteSchema() throws SQLException {
128+
try (Connection connection = DriverManager.getConnection(DB_URL);
129+
Statement statement = connection.createStatement()) {
130+
statement.execute("DROP TABLE CUSTOMERS");
131+
}
132+
}
133+
134+
private void assertCustomerCountIs(int count) {
135+
try (Stream<Customer> allCustomers = dao.getAll()) {
136+
assertTrue(allCustomers.count() == count);
137+
}
138+
}
139+
140+
141+
/**
142+
* An arbitrary number which does not correspond to an active Customer id.
143+
*
144+
* @return an int of a customer id which doesn't exist
145+
*/
146+
private int getNonExistingCustomerId() {
147+
return 999;
148+
}
149+
}

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
<guava.version>19.0</guava.version>
5151
<systemrules.version>1.15.1</systemrules.version>
5252
<mockito.version>1.10.19</mockito.version>
53+
<hierarchical-junit-runner-version>4.12.1</hierarchical-junit-runner-version>
5354
</properties>
5455
<modules>
5556
<module>abstract-factory</module>
@@ -195,6 +196,12 @@
195196
<version>${systemrules.version}</version>
196197
<scope>test</scope>
197198
</dependency>
199+
<dependency>
200+
<groupId>de.bechte.junit</groupId>
201+
<artifactId>junit-hierarchicalcontextrunner</artifactId>
202+
<version>${hierarchical-junit-runner-version}</version>
203+
<scope>test</scope>
204+
</dependency>
198205
</dependencies>
199206
</dependencyManagement>
200207

0 commit comments

Comments
 (0)