我们正在使用无法修改的单元测试类制作一个小型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
方法可能会相互调用,这可能会导致并发症这是否可以通过另一种方法(也许是多线程)来解决?这是我们不久将讨论的主题之一,但是我对此并不十分熟悉,因此我不知道该怎么做,或者根本无法做到。