英文:
Getting NullPointerException in reference to protected variable in JUnit Test subclass
问题
我有一个名为 AnswerQuestionTests
的子类,其中包含几个带有 @Test
注解的 JUnit 测试(我正在运行 JUnit 4)。这个子类继承自一个名为 TestBase
的超类,该超类没有其他测试方法,但包含一些 protected
访问修饰符的变量。我们的想法是,为了减少代码重复,我们希望所有的测试都扩展自 TestBase
,以避免在大多数测试中重复代码以初始化一些模拟服务。
例如,我在 AnswerQuestionTests
中有一个方法,测试徽章的进度是否在数据库中递增:
@Test
public void testBadgeProgressIncremented() {
int badgeProgressBeforeAction = clientModule.badgeClient().getCurrentBadgeActivity();
...
}
在这种情况下,clientModule
是在超类 TestBase
中声明的 protected
变量。这个变量在 TestBase
中的 initialize()
方法中进行初始化,然后在 AnswerQuestionTests
中使用 @BeforeAll
注解调用该方法:
public class AnswerQuestionTests extends TestBase {
@BeforeAll
public void initialize() {
super.initialize();
}
...
}
我使用 Bazel 的 java_test
规则来运行这个测试,它将 test_class
作为参数,我给它传递了 AnswerQuestionTest
类。然而,运行器在引用超类中声明的 clientModule
和所有其他 protected
变量时会产生 NullPointerException
。
我猜想这可能与我对 JUnit 运行器工作方式的了解不足有关,但是否有人能提供一些建议?
编辑:我还使用 @TestInstance(Lifecycle.PER_CLASS)
注解了 AnswerQuestionTests
,以便 JUnit 运行器每个类只创建一个新实例,而不是每个方法创建一个新实例。
编辑 2:问题是 Bazel 的 java_test
运行器本质上是运行 JUnit 4,但我们所有的测试先前都是基于使用 JUnit 5 的假设编写的。已解决。
英文:
I have a subclass AnswerQuestionTests
which contains several JUnit tests annotated with @Test
(I'm running JUnit 4). This subclass extends a superclass TestBase
which has no other test methods, but contains a bunch of protected
variables. The idea we had was that, in order to reduce code duplication, we would have all of our tests extend TestBase
to avoid duplicating code for initialization of some mocked services that most of our tests need.
For example, I have a method in AnswerQuestionTests
which tests whether or not a badge's progress gets incremented in the database:
@Test
public void testBadgeProgressIncremented() {
int badgeProgressBeforeAction = clientModule.badgeClient().getCurrentBadgeActivity();
...
}
In this case, clientModule
is a protected
variable which is declared in the superclass TestBase
. This variable gets initialized in an initialize()
method in TestBase
, which is called from AnswerQuestionTests
using a @BeforeAll
annotation:
public class AnswerQuestionTests extends TestBase {
@BeforeAll
public void initialize() {
super.initialize();
}
...
}
I run this test using Bazel's java_test
rule, which takes a test_class
as a parameter, and I give it the AnswerQuestionTest
class. However, the runner produces a NullPointerException
in reference to clientModule
and all of the other protected
variables declared in the superclass.
I assume this has something to do with my lack of knowledge about how the JUnit runner works, but can anybody offer any advice?
EDIT: I also annotate AnswerQuestionTests
with @TestInstance(Lifecycle.PER_CLASS)
so that the JUnit runner only creates a new instance once per class instead of once per method.
EDIT 2: The issue was that the Bazel java_test
runner natively runs JUnit4, but all of our tests were previously written under the assumption of using JUnit5. Resolved.
答案1
得分: 1
在JUnit4中,此注释称为@BeforeClass
,应该用于一个static
方法上。它会在执行此类中的所有测试方法之前执行。JUnit5的注释将在JUnit4中被忽略。
对于每个方法的执行,JUnit会创建一个AnswerQuestionTests
的新实例,因此您不能在@BeforeClass
中使用实例字段。
一个选择是将初始化的客户端存储在一个静态字段中。
英文:
In junit4 this annotation is called @BeforeClass
and should be on a static
method. It is executed before all test methods in this class are executed. Junit5 annotation will be ignored in junit4
For each method execution Junit creates a new instance of AnswerQuestionTests
, so you can't use instance fields in @BeforeClass
.
One option would be to store the initialized client in a static field.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论