
junit测试中,由于默认的`per_method`实例生命周期,每个测试方法都会创建新的测试类实例,导致类字段(包括`final`字段)在不同测试方法间重新初始化,而非“重载”。通过使用`@testinstance(testinstance.lifecycle.per_class)`可以强制junit为所有测试方法使用同一个实例,从而避免字段重复初始化,但需警惕这可能破坏测试独立性原则。
在编写JUnit单元测试时,开发者可能会观察到一个现象:测试类中的实例字段,特别是final修饰的字段,在不同的测试方法执行时会呈现出不同的值,甚至测试类的哈希码也会发生变化。这使得一些开发者误以为测试类在每次测试方法执行时都被“重载”了。
例如,考虑以下测试类:
import org.apache.commons.lang3.RandomStringUtils; // 假设已引入此依赖
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
class SomeTest {
private final String aRandomString = RandomStringUtils.randomAlphabetic(10);
@Test
void a() {
System.out.println("Method a: " + aRandomString + ", Hash: " + this.hashCode());
}
@Test
void b() {
System.out.println("Method b: " + aRandomString + ", Hash: " + this.hashCode());
}
}在执行a()和b()方法时,aRandomString的值很可能会不同,并且this.hashCode()也会显示不同的值。这并非因为类被重载,而是因为JUnit的默认行为导致了不同的测试实例。
JUnit 5(JUnit Jupiter)引入了TestInstance.Lifecycle枚举来管理测试类的实例生命周期。它有两种主要的模式:
TestInstance.Lifecycle.PER_METHOD (默认值) 这是JUnit的默认行为。在这种模式下,JUnit会为测试类中的每一个测试方法创建一个全新的测试类实例。这意味着:
TestInstance.Lifecycle.PER_CLASS 在这种模式下,JUnit会为整个测试类只创建一个测试类实例。这个单一实例将被该测试类中的所有测试方法共享。这意味着:
要改变JUnit的默认行为,使测试类只创建一个实例,可以使用@TestInstance注解并指定其生命周期为PER_CLASS。
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class SomeTestWithPerClass {
private final String aRandomString = RandomStringUtils.randomAlphabetic(10);
@Test
void a() {
System.out.println("Method a: " + aRandomString + ", Hash: " + this.hashCode());
}
@Test
void b() {
System.out.println("Method b: " + aRandomString + ", Hash: " + this.hashCode());
}
}应用@TestInstance(TestInstance.Lifecycle.PER_CLASS)后,aRandomString的值在a()和b()方法中将保持一致,且this.hashCode()也将相同,因为它指向的是同一个实例。
虽然PER_CLASS模式可以解决字段重复初始化的问题,但在使用时务必谨慎,因为它可能违反单元测试的核心原则:
总结: JUnit默认的PER_METHOD生命周期是确保单元测试独立性的基石。当观察到测试类字段在不同测试方法间变化时,这通常是JUnit为了隔离测试而创建新实例的正常行为。如果确实需要共享测试实例状态(例如,为了性能优化或管理昂贵资源),可以使用@TestInstance(TestInstance.Lifecycle.PER_CLASS)。然而,在使用此模式时,必须仔细权衡其带来的便利性与可能破坏测试独立性的风险,并确保对共享状态进行妥善管理。对于大多数纯粹的单元测试,保持默认的PER_METHOD行为是更稳健的选择。
以上就是理解JUnit测试实例生命周期:为什么类会在测试方法间重载?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号