由于打开了JDBC连接,单元测试无法删除数据库

时间:2019-01-12 17:52:41

标签: java multithreading sqlite jdbc junit

我们正在使用无法修改的单元测试类制作一个小型Java应用程序。该应用程序使用SQLite数据库,并且一个测试类DAOTest对DAO类进行测试。单独运行时,将通过DAOTest中的所有测试,但是当一个接一个地运行时,只有一个通过,其他则失败。

DAO.java:

import java.sql.*;

public class DAO  {
    private Connection conn = null;
    private static final String URL = "jdbc:sqlite:database.db";

    public DAO() {
        try {
            conn = DriverManager.getConnection(URL);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void close() {
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // methodA(), methodB(), ...
}

DAOTest.java

import org.junit.jupiter.api.Test;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

import static org.junit.jupiter.api.Assertions.fail;

public class DAOTest {
    DAO dao = null;

    /**/
    @Test
    void initDb() {
        if (dao != null) {
            dao.close();
        }

        File dbfile = new File("database.db");
        ClassLoader classLoader = getClass().getClassLoader();
        File srcfile = new File(classLoader.getResource("db/databaseToBeCopied.db").getFile());
        Boolean isDbDeleted = false;
        try {

            isDbDeleted = dbfile.delete();
            Files.copy(srcfile.toPath(), dbfile.toPath());
        } catch (IOException e) {
            e.printStackTrace();
            fail("Database deleted: " + isDbDeleted);
        }

        dao = new DAO();
    }

    @Test
    void testA() {
        initDb();
        // Call dao.methodA()...
    }

    @Test
    void testB() {
        initDb();
        // Call dao.methodB()...
    }

}

我了解导致问题的原因。在每次测试开始时都会调用initDb(),将databaseToBeCopied.db复制到database.db。复制函数期望database.db文件不存在,或者抛出FileAlreadyExistsException。由于dao中的DAOTest.java变量是一个non-static属性,因此每次调用initDb()时该变量为null,因此不会调用dao.close(),并且连接到数据库将不会关闭。现在,这将禁用删除database.db,因此复制功能将引发异常,并且测试将失败。我无法修改测试类。

我能想到的唯一可能的解决方案是在DAO.java的每个方法中打开和关闭数据库连接,因此不需要close()函数。这种方法存在两个问题:

  • 我不知道这有多有效
  • DAO.java方法可能会相互调用,这可能会导致并发症
  • 乍一看似乎是个坏习惯

这是否可以通过另一种方法(也许是多线程)来解决?这是我们不久将讨论的主题之一,但是我对此并不十分熟悉,因此我不知道该怎么做,或者根本无法做到。

0 个答案:

没有答案