您能否简单解释一下@TestInstance注解以及它在JUnit 5中的作用?我认为我们可以通过**使我们的字段 *static***达到同样的效果。
@TestInstance
static
4c8rllxm1#
我认为这些文档提供了一个有用的总结:如果您希望JUnit Jupiter在同一个测试示例上执行所有测试方法,只需使用@TestInstance(Lifecycle.PER_CLASS)注解您的测试类。使用此模式时,每个测试类将创建一个新的测试示例。因此,如果您的测试方法依赖于示例变量中存储的状态,您可能需要在@BeforeEach或@AfterEach方法中重置该状态。与默认的“每方法”模式相比,“每类”模式有一些额外的好处。特别是,使用“每类”模式,可以在非静态方法和接口默认方法上声明@BeforeAll和@AfterAll。因此,“每类”模式也可以在@嵌套测试类中使用@BeforeAll和@AfterAll方法。但是您可能已经读过这篇文章,并且您认为将字段设置为静态与将字段声明为示例变量并使用@TestInstance(Lifecycle.PER_CLASS)具有相同的效果,这是正确的。因此,对于“它在JUnit 5中如何有用”这个问题的答案可能是使用@TestInstance...
@TestInstance(Lifecycle.PER_CLASS)
67up9zun2#
引入此注解是为了减少在运行单元测试时创建的对象的数量。将@TestInstance(TestInstance.Lifecycle.PER_CLASS)添加到测试类中可以避免为类中的每个测试创建类的新示例。当在同一个测试类中有很多测试并且该类的示例化开销很大时,这一点特别有用。应谨慎使用此注解。所有单元测试都应相互隔离。如果其中一个测试更改了测试类的状态,则不应使用此功能。将字段设为静态以达到相同的效果并不是一个好主意。这确实会减少创建的对象的数量,但在执行测试类中的所有测试时无法清除这些对象。当您有一个巨大的测试套件时,这可能会导致问题。
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
gblwokeq3#
@TestInstance用于为带注解的测试类或测试接口配置 * 测试示例的生命周期 *:
PER_CLASS
PER_METHOD
如果@TestInstance没有在测试类或由测试类实现的测试接口上显式声明,则生命周期模式将隐式默认为PER_METHOD。将测试示例生命周期模式设置为PER_CLASS将启用以下功能:
@BeforeAll
@AfterAll
@Nested
有关详细信息,请参阅测试示例生命周期文档。
wz1wpwve4#
由于没有人提供一个合适的编码例子,我想给予一个简单的代码样本,如下理解的概念,
Per Method Sample -Junit 5中的默认选项请注意,两个方法是静态的,否则将引发异常,因为类在每个方法中示例化。
@TestInstance(Lifecycle.PER_METHOD) public class MathUtilTestPerMethod { MathUtil util; @BeforeAll static void beforeAllInit() { System.out.println("running before all"); } @AfterAll static void afterAllCleanUp() { System.out.println("running after all"); } @BeforeEach void init() { util = new MathUtil(); System.out.println("running before each..."); } @AfterEach void cleanUp() { System.out.println("running after each..."); } @Test void testSum() { assertEquals(2, util.addtwoNumbers(1, 1)); } }
每个类示例请注意,从两个方法中删除了static,并全局创建了MathUtil对象,而不是在一个方法中创建,因为类只示例化一次。
@TestInstance(Lifecycle.PER_CLASS) public class MathUtilTestPerClass { MathUtil util = new MathUtil(); @BeforeAll void beforeAllInit() { System.out.println("running before all"); } @AfterAll void afterAllCleanUp() { System.out.println("running after all"); } @BeforeEach void init() { System.out.println("running before each..."); } @AfterEach void cleanUp() { System.out.println("running after each..."); } @Test void testSum() { assertEquals(2, util.addtwoNumbers(1, 1)); } }
zujrkrfu5#
这在用Kotlin编写测试时也很有用(因为它没有静态方法)。因此,不要将包含@JvmStatic函数的伴随对象用于@BeforeAll或@AfterAll,而是将生命周期设置为PER_CLASS,并使用@BeforeAll或@AfterAll注解常规方法:
@JvmStatic
@TestInstance(TestInstance.Lifecycle.PER_CLASS) class MyTest { @BeforeAll fun setup() { println("I am invoked only once") } }
使用此方法时,如有必要,请小心重置@BeforeEach或@AfterEach函数中的示例变量。感谢this article的帮助。
@BeforeEach
@AfterEach
5条答案
按热度按时间4c8rllxm1#
我认为这些文档提供了一个有用的总结:
如果您希望JUnit Jupiter在同一个测试示例上执行所有测试方法,只需使用@TestInstance(Lifecycle.PER_CLASS)注解您的测试类。使用此模式时,每个测试类将创建一个新的测试示例。因此,如果您的测试方法依赖于示例变量中存储的状态,您可能需要在@BeforeEach或@AfterEach方法中重置该状态。
与默认的“每方法”模式相比,“每类”模式有一些额外的好处。特别是,使用“每类”模式,可以在非静态方法和接口默认方法上声明@BeforeAll和@AfterAll。因此,“每类”模式也可以在@嵌套测试类中使用@BeforeAll和@AfterAll方法。
但是您可能已经读过这篇文章,并且您认为将字段设置为静态与将字段声明为示例变量并使用
@TestInstance(Lifecycle.PER_CLASS)
具有相同的效果,这是正确的。因此,对于“它在JUnit 5中如何有用”这个问题的答案可能是使用
@TestInstance
...@TestInstance
的使用不太可能是偶然的,或者是未经考虑的复制和粘贴的结果。67up9zun2#
引入此注解是为了减少在运行单元测试时创建的对象的数量。
将
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
添加到测试类中可以避免为类中的每个测试创建类的新示例。当在同一个测试类中有很多测试并且该类的示例化开销很大时,这一点特别有用。应谨慎使用此注解。所有单元测试都应相互隔离。如果其中一个测试更改了测试类的状态,则不应使用此功能。
将字段设为静态以达到相同的效果并不是一个好主意。这确实会减少创建的对象的数量,但在执行测试类中的所有测试时无法清除这些对象。当您有一个巨大的测试套件时,这可能会导致问题。
gblwokeq3#
@TestInstance
用于为带注解的测试类或测试接口配置 * 测试示例的生命周期 *:PER_CLASS
:每个测试类将创建一次新的测试示例。PER_METHOD
:将为每个测试方法、测试工厂方法或测试模板方法创建一个新的测试示例。此模式类似于JUnit版本1到4中的行为。如果
@TestInstance
没有在测试类或由测试类实现的测试接口上显式声明,则生命周期模式将隐式默认为PER_METHOD
。将测试示例生命周期模式设置为
PER_CLASS
将启用以下功能:@BeforeAll
和@AfterAll
方法之间共享测试示例状态。@Nested
测试类中@BeforeAll
和@AfterAll
方法的声明。@BeforeAll
和@AfterAll
。@BeforeAll
和@AfterAll
方法的声明。有关详细信息,请参阅测试示例生命周期文档。
wz1wpwve4#
由于没有人提供一个合适的编码例子,我想给予一个简单的代码样本,如下理解的概念,
Per Method Sample -Junit 5中的默认选项请注意,两个方法是静态的,否则将引发异常,因为类在每个方法中示例化。
每个类示例请注意,从两个方法中删除了static,并全局创建了MathUtil对象,而不是在一个方法中创建,因为类只示例化一次。
zujrkrfu5#
这在用Kotlin编写测试时也很有用(因为它没有静态方法)。
因此,不要将包含
@JvmStatic
函数的伴随对象用于@BeforeAll
或@AfterAll
,而是将生命周期设置为PER_CLASS
,并使用@BeforeAll
或@AfterAll
注解常规方法:使用此方法时,如有必要,请小心重置
@BeforeEach
或@AfterEach
函数中的示例变量。感谢this article的帮助。