我在运行一些单元测试时遇到了一些有趣的事情。我有以下方法:
private void createSchemaIfNecessary() throws SQLException, IOException{
if(!schemaExists){
try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement();) {
statement.execute(getSQLByFileName(GOLF_COURSE_TABLE_CREATION_SCRIPT));
statement.execute(getSQLByFileName(GOLF_COURSE_HOLE_TABLE_CREATION_SCRIPT));
connection.commit();
schemaExists = true;
}
}
}
每个单元测试都会调用此方法来确定是否创建表。 schemaExists
变量是成员变量。我注意到,当每个测试都在运行时,有些情况下即使在点击schemaExists = true;
行之后,下次调用该方法时,schemaExists
也会被评估为false。然后我将变量设为静态,这解决了问题。
由于单个单元测试正在运行,它们是否都在单元测试类的单个实例的上下文中运行?
答案 0 :(得分:3)
我将假设schemaExists
是您的测试类的非静态成员。
在调用测试方法(带注释的@Test
)之前,junit(默认情况下)会创建测试类的新实例(More detail here)。
因此,任何非静态类成员都将根据类中的定义进行初始化。如果未显式初始化,则它们将被设置为默认值,因此如果schemaExists
为boolean
(原语)然后false
。
如果你想为所有要分享的测试设置一些内容,我建议你想要做的是创建一个@BeforeClass
静态方法来初始化静态属性。
以下是OP中数据库架构初始化代码的示例:
@BeforeClass
public static void setupDBOnce() {
Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement();
statement.execute(getSQLByFileName(GOLF_COURSE_TABLE_CREATION_SCRIPT));
statement.execute(getSQLByFileName(GOLF_COURSE_HOLE_TABLE_CREATION_SCRIPT));
connection.commit();
}
如果由于某种原因你不想要这种行为(每个测试方法运行一个实例)you can do any of these:
@TestInstance(Lifecycle.PER_CLASS)
-Djunit.jupiter.testinstance.lifecycle.default=per_class
junit-platform.properties
的现有属性文件:junit.jupiter.testinstance.lifecycle.default = per_class
如果你覆盖了默认值,那么值得记住的一个注意事项是:
使用此模式时,每个测试类将创建一个新的测试实例。因此,如果您的测试方法依赖于存储在实例变量中的状态,则可能需要在@BeforeEach或@AfterEach方法中重置该状态。