如何测试对成功和不成功的数据库连接 (JDBC) 的响应?

How do I test responses to successful and nonsuccessful database connections (JDBC)?

下面是我的代码。我一直在尝试不同的测试方法,包括存根、模拟和间谍。当我尝试模拟 DriverManager.getConnection() 时,我收到一条消息说它是私有的。我正在尝试练习 TDD,所以我知道测试连接本身并不是目的,而是围绕连接的行为。

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);
    }
}

许多开发人员可能会争辩说此测试没有意义,但在某些情况下,您可能希望测试连接在使用后是否已成功关闭(例如:如果您发现错误发生是因为您的程序超过给定资源的最大连接数,TDD 鼓励您为此错误修复添加测试)。为了做到这一点

  1. 通过添加测试来设计方法接口并使其失败(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());
    }
    
  2. 使conn成为Dataset的属性class

  3. 在数据集中实现 close() 方法 class

  4. 将 isClosed() 方法添加到数据集 class 以公开连接状态(例如 dataset.isClosed()、class Dataset.java) .

    public boolean isClosed() {
       return this.conn.isClosed();
    }
    
  5. 重复连接未关闭且应 return false 的情况。