我有一个子类AnswerQuestionTests,其中包含几个用@Test注释的JUnit测试(我正在运行JUnit 4)。该子类扩展了超类TestBase,该超类没有其他测试方法,但包含一堆protected变量。我们的想法是,为了减少代码重复,我们将所有测试扩展为TestBase以避免重复代码以初始化大多数测试所需的某些模拟服务。

例如,我在AnswerQuestionTests中有一个方法可以测试徽章的进度在数据库中是否增加:

@Test
public void testBadgeProgressIncremented() {
    int badgeProgressBeforeAction = clientModule.badgeClient().getCurrentBadgeActivity();
    ...
}


在这种情况下,clientModule是在超类protected中声明的TestBase变量。此变量在initialize()中的TestBase方法中初始化,该方法使用AnswerQuestionTests批注从@BeforeAll调用:

public class AnswerQuestionTests extends TestBase {
    @BeforeAll
    public void initialize() {
        super.initialize();
    }
    ...
}


我使用Bazel的java_test规则运行此测试,该规则将test_class作为参数,并将其赋予AnswerQuestionTest类。但是,运行程序会引用超类中声明的NullPointerException和所有其他clientModule变量生成一个protected

我认为这与我对JUnit运行器的工作原理缺乏了解有关,但是有人可以提供任何建议吗?

编辑:我也用AnswerQuestionTests注释@TestInstance(Lifecycle.PER_CLASS),以便JUnit运行器每个类只创建一个新实例,而不是每个方法一次。

编辑2:问题是Bazel java_test运行程序本机运行JUnit4,但是我们所有的测试以前都是在使用JUnit5的假设下编写的。解决。

最佳答案

在junit4中,此注释称为@BeforeClass,应在static方法上。它在执行该类中的所有测试方法之前执行。 Junit5注释将在junit4中被忽略

Junit会为每个方法执行创建AnswerQuestionTests的新实例,因此您不能在@BeforeClass中使用实例字段。

一种选择是将初始化的客户端存储在静态字段中。

09-30 20:31