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

发布于 2025-01-15 14:25:50 字数 3327 浏览 2 评论 0原文

下面是我的代码。我一直在尝试不同的测试方法,包括存根、嘲笑和间谍。当我尝试模拟 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);
    }
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

樱&纷飞 2025-01-22 14:25:50

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

  1. 通过添加测试来设计方法接口并使其失败(DatasetTest.java 类):

    public void whenDatasetClosed_closeReturnsTrue() {
       //安排
       //创建数据集类的新数据集实例
       数据集 dataset = new Dataset();
    
       //行为
       数据集.close();
    
      //断言
      assertTrue(dataset.isClosed());
    }
    
  2. 使 conn 成为 Dataset 类的属性

  3. 在 Dataset 类中实现 close() 方法

  4. 将 isClosed() 方法添加到公开连接状态的 Dataset 类(例如 dataset.isClosed()、Dataset.java 类)。

    public boolean isClosed() {
       返回 this.conn.isClosed();
    }
    
  5. 对于连接未关闭且应返回 false 的情况,重复此操作。

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

  1. 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());
    }
    
  2. make conn an attribute of Dataset class

  3. Implement close() method in Dataset class

  4. 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();
    }
    
  5. Repeat for the case where the connection is not closed and should return false.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文