Hi everyone i'm new here and i need your help to unit test with junit a DAO class with a connection pool. This is the ConPool:
public class ConPool {
private static DataSource datasource;
/**
* {@return} Connection
* {@throws} SQLException
* Ritorna la connessione al db.
*/
public static Connection getConnection() throws SQLException {
if (datasource == null) {
PoolProperties p = new PoolProperties();
p.setUrl("jdbc:mysql://localhost:3306/GameLand?serverTimezone="
+ TimeZone.getDefault().getID());
p.setDriverClassName("com.mysql.cj.jdbc.Driver");
p.setUsername("root");
p.setPassword("basedidati");
p.setMaxActive(100);
p.setInitialSize(10);
p.setMinIdle(10);
p.setRemoveAbandonedTimeout(60);
p.setRemoveAbandoned(true);
datasource = new DataSource();
datasource.setPoolProperties(p);
}
return datasource.getConnection();
}
}
and this is the DAO class that i want to test:
public class OrdineDAO {
/**
* {@return} ArrayList of Ordine.
*/
public synchronized ArrayList<Ordine> doRetrieveAll() {
String query = "SELECT * FROM ordine";
ArrayList<Ordine> result = new ArrayList<Ordine>();
try (Connection conn = ConPool.getConnection()) {
PreparedStatement ps = conn.prepareStatement(query);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Ordine ord = new Ordine();
ord.setConsegnato(rs.getBoolean("consegnato"));
ord.setDataOra(rs.getString("dataOra"));
ord.setIdOrdine(rs.getInt("idOrdine"));
ord.setIdProdotto(rs.getInt("idProdotto"));
ord.setPrezzoFis(rs.getDouble("prezzoFis"));
ord.setPrezzoDig(rs.getDouble("prezzoDig"));
ord.setIva(rs.getDouble("iva"));
ord.setQuantitaDigitale(rs.getInt("quantitaDigitale"));
ord.setQuantitaFisico(rs.getInt("quantitaFisico"));
ord.setIdUtente(rs.getInt("idUtente"));
result.add(ord);
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
/**
* {@param} id: int.
* {@return} ArrayList of Ordine.
*/
public synchronized ArrayList<Ordine> doRetrieveByUser(int id) {
PreparedStatement ps = null;
String query = "SELECT * FROM ordine WHERE idUtente = ?";
ArrayList<Ordine> result = new ArrayList<Ordine>();
try (Connection conn = ConPool.getConnection()) {
ps = conn.prepareStatement(query);
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Ordine ord = new Ordine();
ord.setConsegnato(rs.getBoolean("consegnato"));
ord.setDataOra(rs.getString("dataOra"));
ord.setIdOrdine(rs.getInt("idOrdine"));
ord.setIdProdotto(rs.getInt("idProdotto"));
ord.setPrezzoFis(rs.getDouble("prezzoFis"));
ord.setPrezzoDig(rs.getDouble("prezzoDig"));
ord.setIva(rs.getDouble("iva"));
ord.setQuantitaDigitale(rs.getInt("quantitaDigitale"));
ord.setQuantitaFisico(rs.getInt("quantitaFisico"));
ord.setIdUtente(rs.getInt("idUtente"));
result.add(ord);
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
/**
* {@param} data1: String.
* {@param} data2: String.
* {@return} ArrayList of Ordine.
*/
public synchronized ArrayList<Ordine> doRetrieveByDate(String data1, String data2) {
PreparedStatement ps = null;
String query = "SELECT * FROM ordine WHERE dataOra >= ? AND dataOra <= ?";
ArrayList<Ordine> result = new ArrayList<Ordine>();
try (Connection conn = ConPool.getConnection()) {
ps = conn.prepareStatement(query);
ps.setString(1, data1);
ps.setString(2, data2);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Ordine ord = new Ordine();
ord.setConsegnato(rs.getBoolean("consegnato"));
ord.setDataOra(rs.getString("dataOra"));
ord.setIdOrdine(rs.getInt("idOrdine"));
ord.setIdProdotto(rs.getInt("idProdotto"));
ord.setPrezzoFis(rs.getDouble("prezzoFis"));
ord.setPrezzoDig(rs.getDouble("prezzoDig"));
ord.setIva(rs.getDouble("iva"));
ord.setQuantitaDigitale(rs.getInt("quantitaDigitale"));
ord.setQuantitaFisico(rs.getInt("quantitaFisico"));
ord.setIdUtente(rs.getInt("idUtente"));
result.add(ord);
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
}
starting first with doRetrieveAll method, i tried to do a
@Test
public void doRetrieveAll_Success() throws SQLException {
assertNotNull(ordineDAO.doRetrieveAll());
}
But i need to know how to set the @BeforeAll in order to test this method. Can you please help me understanding how to set properly the test class? Thank you
You can use PowerMockito to achieve this. Only reason why I mentioned PowerMockito instead of Mockito is because your getConnection()
method is static and it's easier to mock static methods using PowerMockito
You need to add the below dependencies to get PowerMockito working.
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4-rule</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
Here is the Test method.
import static org.mockito.Matchers.any;
import static org.powermock.api.mockito.PowerMockito.when;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(ConPool.class)
public class OrdineDAOTest {
@Mock
private Connection c;
@Mock
private PreparedStatement stmt;
@Mock
private ResultSet rs;
@Test
public void testDoRetrieveAll() {
try {
//Mocking the Static ConPool Class
PowerMockito.mockStatic(ConPool.class);
//Making the ConPool.getConnection() method to return Mocked Connection
when(ConPool.getConnection()).thenReturn(c);
//Making the prepareStatement method to return Mocked PrepareStatement
when(c.prepareStatement(any(String.class))).thenReturn(stmt);
// Mocking the Values in ResultSet
when(rs.getInt("idOrdine")).thenReturn(10);
//This means result set has only one set of result
//Mocking rs.next() to return true first and then return false the second time
when(rs.next()).thenReturn(true).thenReturn(false);
//Making executeQuery() method to return mocked resultset
when(stmt.executeQuery()).thenReturn(rs);
OrdineDAO dao = new OrdineDAO();
// Invoking the actual method from dao
ArrayList<Ordine> list = dao.doRetrieveAll();
//Comparing the expected vs actual
Assert.assertEquals(1, list.size());
Assert.assertEquals(10, list.get(0).getIdOrdine());
} catch (Exception e) {
e.printStackTrace();
}
}
}
I have explained the code with the commented lines.
I have tested it myself on java 8 along with the above mentioned dependencies and everything works fine for me.
Great, It works fine. thank you much. I'd like to see how to create this test case using mockito, Also. when i will test the doRetrieveByUser and the doRetrieveByDate i don't know if i have to test the success/fail scenario (passing good/wrong arguments) or i can write these tests in the "same" way as the doRetrieveAll test case. Hope it is clear.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.