Objective
In this tutorial, we will learn how to write a Junit testcase for DAO (Data Access Object) class. This tutorial is illustrated with an application of client management.
Before starting with this tutorial, you should read the basic JUnit and DAO pattern.
System architecture
An application of client management is composed of only one DAO class, that is ClientDAO. This class use an entity class, that is Client, to manipulate in the followings methods:
- search client by name (all clients whose name contains the key will be returned)
- get a client by its id (full matching)
- get all clients in the database
- add new client into the database
- edit an existing client
- delete an existing client
In order to test this ClientDAO class, we need a JUnit test class, that is ClientDAOJUTest class, which had at least a test case for each method of the ClientDAO class.
In order to reduce the complexity of the JUnit test class, we could write all necessary Junit testcase of a method in ClientDAO class in a corresponding test method in ClientDAOJUTest class.
An other note: In order to reuse the connection from the ClientDAOJUTest class, we set the variable con to public in the class ClientDAO (This is for the JUnit test only, in general, it should be set as private).

Database before testing
At the database level, there is only one table, that is tblClient, which has five columns: id (primary key, auto increment), name, address, tel, email, note. And assume that the data in the table is as following:

Code of Client.java
import java.io.Serializable;
public class Client implements Serializable{
private static final long serialVersionUID = 2018040801L;
private int id;
private String name;
private String address;
private String tel;
private String email;
private String note;
public Client() {
super();
}
public Client(String name, String address, String tel, String email, String note) {
super();
this.name = name;
this.address = address;
this.tel = tel;
this.email = email;
this.note = note;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
Code of ClientDAO.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
public class ClientDAO {
public static Connection con;
public ClientDAO(){
if(con == null){
String dbUrl = "jdbc:mysql://localhost:3306/hotel";
String dbClass = "com.mysql.jdbc.Driver";
try {
Class.forName(dbClass);
con = DriverManager.getConnection (dbUrl, "root", "12345678");
}catch(Exception e) {
e.printStackTrace();
}
}
}
/**
* search all clients in the tblClient whose name contains the @key
* @param key
* @return list of client whose name contains the @key
*/
public ArrayList<Client> searchClient(String key){
ArrayList<Client> result = new ArrayList<Client>();
String sql = "SELECT * FROM tblClient WHERE name LIKE ?";
try{
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, "%" + key + "%");
ResultSet rs = ps.executeQuery();
while(rs.next()){
Client client = new Client();
client.setId(rs.getInt("id"));
client.setName(rs.getString("name"));
client.setAddress(rs.getString("address"));
client.setTel(rs.getString("tel"));
client.setEmail(rs.getString("email"));
client.setNote(rs.getString("note"));
result.add(client);
}
}catch(Exception e){
e.printStackTrace();
}
return result;
}
/**
* get a client whose id is @key
* @param key
* @return
*/
public Client getClientById(int key){
Client client = null;
String sql = "SELECT * FROM tblClient WHERE id=?";
try{
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, key);
ResultSet rs = ps.executeQuery();
if(rs.next()){
client = new Client();
client.setId(rs.getInt("id"));
client.setName(rs.getString("name"));
client.setAddress(rs.getString("address"));
client.setTel(rs.getString("tel"));
client.setEmail(rs.getString("email"));
client.setNote(rs.getString("note"));
}
}catch(Exception e){
e.printStackTrace();
}
return client;
}
/**
* get all client from tblClient
* @return
*/
public ArrayList<Client> getAllClient(){
ArrayList<Client> result = new ArrayList<Client>();
String sql = "SELECT * FROM tblClient";
try{
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while(rs.next()){
Client client = new Client();
client.setId(rs.getInt("id"));
client.setName(rs.getString("name"));
client.setAddress(rs.getString("address"));
client.setTel(rs.getString("tel"));
client.setEmail(rs.getString("email"));
client.setNote(rs.getString("note"));
result.add(client);
}
}catch(Exception e){
e.printStackTrace();
}
return result;
}
/**
* add a new @client into the DB
* @param client
*/
public void addClient(Client client){
String sql = "INSERT INTO tblClient(name, address, tel, email, note) VALUES(?,?,?,?,?)";
try{
PreparedStatement ps = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, client.getName());
ps.setString(2, client.getAddress());
ps.setString(3, client.getTel());
ps.setString(4, client.getEmail());
ps.setString(5, client.getNote());
ps.executeUpdate();
//get id of the new inserted client
ResultSet generatedKeys = ps.getGeneratedKeys();
if (generatedKeys.next()) {
client.setId(generatedKeys.getInt(1));
}
}catch(Exception e){
e.printStackTrace();
}
}
/**
* update the @client
* @param client
*/
public void editClient(Client client){
String sql = "UPDATE tblClient SET name=?, address=?, tel=?, email=?, note=? WHERE id=?";
try{
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, client.getName());
ps.setString(2, client.getAddress());
ps.setString(3, client.getTel());
ps.setString(4, client.getEmail());
ps.setString(5, client.getNote());
ps.setInt(6, client.getId());
ps.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}
}
/**
* delete the client whose id is @id
* @param id
*/
public void deleteClient(int id){
String sql = "DELETE FROM tblClient WHERE id=?";
try{
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, id);
ps.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}
}
}
JUnit test method for each DAO method
JUnit test for search client method: In this method, we have to test at least two cases: In the case of exception, we need to give a keyword that no client in the tblClient satisfy, therefore, the size of returned list is zero (not null). In the code, we test two testcases in this case with the keyword is “xxxxxxxxxx” and “rn”, respectively.
In the standard case, we need to give a keyword that there is at least a client in the tblClient satisfies. Therefore, the size of the returned list must be greater than zero, and for each element in the list, the name of the client have to contain the entered keyword. In the code, we test two testcases in this case with the keyword is “r” (3 clients returned) and “n” (2 clients returned), respectively.
@Test
public void testSearchClient(){
ClientDAO cd = new ClientDAO();
//exception scenario 1
String key = "xxxxxxxxxx";
ArrayList<Client> listClient = cd.searchClient(key);
Assert.assertNotNull(listClient);
Assert.assertEquals(0, listClient.size());
//exception scenario 2
key = "rn";
listClient = cd.searchClient(key);
Assert.assertNotNull(listClient);
Assert.assertEquals(0, listClient.size());
//standard scenario 1
key = "r";
listClient = cd.searchClient(key);
Assert.assertNotNull(listClient);
Assert.assertEquals(3, listClient.size());
for(int i=0; i<listClient.size(); i++){
Assert.assertTrue(listClient.get(i).getName().toLowerCase().contains(key.toLowerCase()));
}
//standard scenario 2
key = "n";
listClient = cd.searchClient(key);
Assert.assertNotNull(listClient);
Assert.assertEquals(2, listClient.size());
for(int i=0; i<listClient.size(); i++){
Assert.assertTrue(listClient.get(i).getName().toLowerCase().contains(key.toLowerCase()));
}
return;
}
JUnit test for method get client by ID: In this method, we also need to test with two cases: In the exceptional case, we have to give an id which does not exist in the tblClient (In this test we give id=1). Consequently, the expected result is a null object.
In the standard case, we have to give an existed id in the tblClient (we test with id=2). Therefore the expected result is an object with full attribute values as the same as that in the tblClient.
@Test
public void testGetClientById(){
ClientDAO cd = new ClientDAO();
//exception scenario
Client client = cd.getClientById(1);
Assert.assertNull(client);
//standard scenario
client = cd.getClientById(2);
Assert.assertNotNull(client);
Assert.assertEquals("Federer", client.getName());
Assert.assertEquals("federer@abc.com", client.getEmail());
Assert.assertEquals("4321", client.getTel());
return;
}
JUnit test for method get all clients: In this method, we need to test the returned list is not null and its size is the same to the total number of clients in the tblClient.
@Test
public void testGetAllClient(){
ClientDAO cd = new ClientDAO();
ArrayList<Client> listClient = cd.getAllClient();
Assert.assertNotNull(listClient);
Assert.assertEquals(6, listClient.size());
return;
}
JUnit test for method add new client: In this method, we need to test the new inserted id (must be greater than the current maximal id in the tblClient). The total number of client after adding (must be 7). And check whether the new inserted client in the tblClient is identical to the original one.
Note that the method add client modifies the tblClient each time of running the test, we thus have to rollback the original data in the table after each time of running this testcase. That’s why we need to use the connection to commit the transaction manually.
@Test
public void testAddClient(){
ClientDAO cd = new ClientDAO();
Client sClient = new Client("ju test", "HN", "951", "xxx@xxx.com",null);
Connection con = cd.con;
try{
con.setAutoCommit(false);
cd.addClient(sClient);
Assert.assertNotNull(sClient);
Assert.assertTrue(8 < sClient.getId()); // test correct id
Assert.assertEquals(7, cd.getAllClient().size()); // test all row in the table
//test the new inserted row
Client client = cd.getClientById(sClient.getId());
Assert.assertEquals(sClient.getName(), client.getName());
Assert.assertEquals(sClient.getEmail(), client.getEmail());
Assert.assertEquals(sClient.getTel(), client.getTel());
Assert.assertEquals(sClient.getAddress(), client.getAddress());
Assert.assertEquals(sClient.getNote(), client.getNote());
}catch(Exception e){
e.printStackTrace();
}finally{
try{
con.rollback();
con.setAutoCommit(true);
}catch(Exception e){
e.printStackTrace();
}
}
return;
}
JUnit test for method edit client: In this method, we need to test in the case edit a client, and then, get its information to test whether it is the same to the original object.
This method also modifies the tblClient each time of running, so we also need to rollback data of the table after each time running the test.
@Test
public void testEditClient(){
ClientDAO cd = new ClientDAO();
Client sClient = new Client();
Connection con = cd.con;
try{
con.setAutoCommit(false);
cd.addClient(sClient);
String newName = "new ju test";
String newAddress = "new add";
String newEmail = "newemail@abc.com";
String newTel = "new123";
String newNote = "new note";
sClient.setName(newName);
sClient.setAddress(newAddress);
sClient.setEmail(newEmail);
sClient.setTel(newTel);
sClient.setNote(newNote);
cd.editClient(sClient);
//test the new updated row
Client client = cd.getClientById(sClient.getId());
Assert.assertEquals(newName, client.getName());
Assert.assertEquals(newEmail, client.getEmail());
Assert.assertEquals(newTel, client.getTel());
Assert.assertEquals(newAddress, client.getAddress());
Assert.assertEquals(newNote, client.getNote());
}catch(Exception e){
e.printStackTrace();
}finally{
try{
con.rollback();
con.setAutoCommit(true);
}catch(Exception e){
e.printStackTrace();
}
}
return;
}
JUnit test for method delete a client: In this method, we need to test the total number client remaining in the tblClient (add and then delete it, so it must be 6). And then, we have to test if the client with that id is still existent in the tblClient.
Note that this method also modifies the tblClient after each time running the testcase, so we also need to rollback the data of the table after each run.
@Test
public void testDeleteClient(){
ClientDAO cd = new ClientDAO();
Client sClient = new Client("ju test", "HN", "951", "xxx@xxx.com",null);
Connection con = cd.con;
try{
con.setAutoCommit(false);
cd.addClient(sClient);
cd.deleteClient(sClient.getId());
Assert.assertEquals(6, cd.getAllClient().size()); // test all row in the table
//test the new deleted row
Client client = cd.getClientById(sClient.getId());
Assert.assertNull(client);
}catch(Exception e){
e.printStackTrace();
}finally{
try{
con.rollback();
con.setAutoCommit(true);
}catch(Exception e){
e.printStackTrace();
}
}
return;
}
Now you can regroup these parts of code into a class of ClientDAOJUTest to run it.