Issue
Below is code that I have. I've been trying different ways to test, including stubbing, mocking and spying. When I tried mocking the DriverManager.getConnection(), I got a message that it's private. I'm trying to practice TDD, so I know that it's not the intention to test the connection itself but rather the behavior surrounding the connection.
public class Main {
public static void main(String[] args) {
Datasource datasource = new Datasource();
if(datasource.open() == false){
return;
}
datasource.close();
}
}
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Datasource {
public static final String DB_NAME = "DBNAME";
public static final String DB_USERNAME = "USERNAME";
public static final String DB_PASSWORD = "PASSWORD";
public static final String SUBPROTOCOL = "jdbc:oracle:thin:@";
public static final String SERVER_NAME = "SERVERNAME";
public static final String PORT_NUMBER = "1521";
public static final String CONNECTION_STRING = SUBPROTOCOL + SERVER_NAME + ":" + PORT_NUMBER + "/" + DB_NAME;
private Connection conn;
public boolean open(){
try {
conn = DriverManager.getConnection(CONNECTION_STRING, DB_USERNAME, DB_PASSWORD);
System.out.println("Connected to database successfully.");
return true;
} catch (SQLException e) {
System.out.println("Error connecting to database: " + e.getMessage());
return false;
}
}
/**
* Closes the connection to the HR database.
* @return void
*/
public void close() {
try {
if (conn != null) {
conn.close();
System.out.println("Closed database connection successfully.");
}
} catch (SQLException e) {
System.out.println("Error closing database connection: " + e.getMessage());
}
}
}
import static org.junit.jupiter.api.Assertions.*;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Spy;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
class DatasourceTest {
@Test
void exceptionIsThrownIfHRDatabaseConnectionFails() throws SQLException {
//Datasource testDatasource = new Datasource();
//assertThrows(SQLException.class, () -> {testDatasource.open();});
//TODO come back to this to mock connection
Datasource testDatasource = mock(Datasource.class);
DriverManager testDriverManager = mock(DriverManager.class);
when(testDriverManager.getConnection(Datasource.CONNECTION_STRING, Datasource.DB_USERNAME, Datasource.DB_PASSWORD)).thenReturn(null);
assertThrows(SQLException.class, () -> {testDatasource.open();});
}
@Test
void exceptionIsThrownIfConnectionIsNullDuringClose() throws SQLException {
Datasource testDatasource = new Datasource();
DriverManager testDriverManager = mock(DriverManager.class);
when(testDriverManager.getConnection(Datasource.CONNECTION_STRING, Datasource.DB_USERNAME, Datasource.DB_PASSWORD)).thenReturn(null);
}
}
Solution
Many developers may argue this test does not make sense, but in some cases you may want to test that a connection was successfully closed after using it (eg: if you find that a bug was happening because your program was exceeding the max number of connections for a giving resource, TDD encourages you to adding a test for this bugfix). In order to do this
Design the method interface by adding a test and make it fail (class DatasetTest.java):
public void whenDatasetClosed_closedReturnsTrue() { //Arrange //create a new dataset instance of your Dataset Class Dataset dataset = new Dataset(); //Act dataset.close(); //Assert assertTrue(dataset.isClosed()); }
make conn an attribute of Dataset class
Implement close() method in Dataset class
Add the isClosed() method to the Dataset class exposing the connection status (eg. dataset.isClosed(), class Dataset.java).
public boolean isClosed() { return this.conn.isClosed(); }
Repeat for the case where the connection is not closed and should return false.
Answered By - JackCid
Answer Checked By - Robin (JavaFixing Admin)