我正在使用JUnit编写一些测试用例。我需要初始化一些静态变量,这些变量将用于该类中的所有测试用例。为此,我可以使用1.静态初始值设定项块或1.使用@BeforeClass的静态方法使用其中一种方法比使用另一种方法有哪些优势?
@BeforeClass
jvlzgdj91#
@BeforeClass或static初始化器有非常不同的语义。静态初始化器由JVM调用,而不是由JUnit调用。如果在静态初始值设定项中引发异常,则测试框架可能无法捕获和报告该异常。此外,与@BeforeClass方法相比,静态初始化器的调用时间定义不明确。它将在每个类加载器第一次实际 * 使用 * 时只运行一次,例如访问静态属性,静态方法或其构造函数之一。有时候,可能很难弄清楚这将是什么时候。(如果你不使用继承:也许有一天你的同事会重构你的测试用例。如果不是今天,静态初始化器的选择可能会在未来引入讨厌的bug。另一方面,@BeforeClass在每个类的测试运行之前运行。如果一个类要进行不同的测试,例如,由于基于继承构建的测试,static初始化器将仅在使用该类的第一个测试中运行。这意味着您使测试顺序依赖于您永远不想要的东西。请注意,这两个选项之间的语义差异比使用@Before或测试构造函数之间的语义差异更大。作为最后一个论点,想想注解的文献价值。它使你的意图更容易理解。此规则的唯一例外是不可变常量。为了保持代码的简洁性和遵守compile time constants,应该在它们的声明中初始化它们。如果你的值是可变的,你就不应该使用static值。同样,在测试中改变的可变值会给测试带来顺序依赖,这是应该避免的。TL;DR:使用@BeforeClass!
static
@Before
z9smfwbn2#
在决定使用static initialization block还是@BeforeClass时,可以考虑以下几点:
@AfterClass
private static final String VARIABLE
oaxa6hgo3#
如果是static和final,那么你只有一个选择:静态初始化器编译器将阻止您从方法内部写入final字段,无论是否为静态。编辑:好的,你已经从你的问题中删除了“最终”这个词。在这种情况下,它几乎没有区别。静态初始化器将运行一次;@BeforeClass方法也是如此。随便挑一个你认为更有可读性的。
final
deikduxw4#
这不是完全一样的行为。@BeforeClass在每次测试运行时运行,静态初始化器仅在类加载时运行一次。如果您的testrunner使用相同的类加载器,那么在@BeforeClass的情况下,您将重新运行静态变量的初始化。这取决于你想在这里实现什么。
4条答案
按热度按时间jvlzgdj91#
@BeforeClass
或static
初始化器有非常不同的语义。静态初始化器由JVM调用,而不是由JUnit调用。如果在静态初始值设定项中引发异常,则测试框架可能无法捕获和报告该异常。此外,与
@BeforeClass
方法相比,静态初始化器的调用时间定义不明确。它将在每个类加载器第一次实际 * 使用 * 时只运行一次,例如访问静态属性,静态方法或其构造函数之一。有时候,可能很难弄清楚这将是什么时候。(如果你不使用继承:也许有一天你的同事会重构你的测试用例。如果不是今天,静态初始化器的选择可能会在未来引入讨厌的bug。另一方面,
@BeforeClass
在每个类的测试运行之前运行。如果一个类要进行不同的测试,例如,由于基于继承构建的测试,static
初始化器将仅在使用该类的第一个测试中运行。这意味着您使测试顺序依赖于您永远不想要的东西。请注意,这两个选项之间的语义差异比使用
@Before
或测试构造函数之间的语义差异更大。作为最后一个论点,想想注解的文献价值。它使你的意图更容易理解。此规则的唯一例外是不可变常量。为了保持代码的简洁性和遵守compile time constants,应该在它们的声明中初始化它们。如果你的值是可变的,你就不应该使用
static
值。同样,在测试中改变的可变值会给测试带来顺序依赖,这是应该避免的。TL;DR:使用
@BeforeClass
!z9smfwbn2#
在决定使用static initialization block还是
@BeforeClass
时,可以考虑以下几点:@BeforeClass
是@AfterClass
的拮抗剂。因此,如果您进行的初始化需要稍后进行清理(例如打开外部资源),那么(从语义的Angular 来看)使用带注解的方法会更好。1.如果你做了复杂的初始化,可能会抛出检查异常,那么使用
@BeforeClass
会舒服得多,因为你不必捕捉它并将它 Package 成一个未检查异常。1.如果你想使用constant semantics(
private static final String VARIABLE
)进行复杂的初始化,你将别无选择,只能使用静态初始化块或静态方法。有一个关于SO的文章:unit testing - What's the difference between using @BeforeClass and using instance or static variable in JUnit 4 Java?
oaxa6hgo3#
如果是
static
和final
,那么你只有一个选择:静态初始化器编译器将阻止您从方法内部写入final字段,无论是否为静态。
编辑:好的,你已经从你的问题中删除了“最终”这个词。在这种情况下,它几乎没有区别。静态初始化器将运行一次;@BeforeClass方法也是如此。随便挑一个你认为更有可读性的。
deikduxw4#
这不是完全一样的行为。
@BeforeClass
在每次测试运行时运行,静态初始化器仅在类加载时运行一次。如果您的testrunner使用相同的类加载器,那么在@BeforeClass
的情况下,您将重新运行静态变量的初始化。这取决于你想在这里实现什么。