JUnit 5 @Nested 注释的目的是什么
What's the purpose of the JUnit 5 @Nested annotation
在 JUnit 5 中,有一个新的注解:@Nested
。
我明白注释是如何工作的,我明白为什么我们使用嵌套类,
我只是不明白为什么我们需要 嵌套测试 类.
@Nested
注释允许您拥有一个内部 class,它本质上是一个测试 class,允许您将多个测试 class 分组在同一个父项下(具有相同的初始化)。
我所有的测试都需要一个数据库服务器运行。我的大部分测试还需要数据库中的用户 table,才能登录。除此之外,一些测试需要好友 table,才能登录和查询好友。
每个资源都有设置和拆卸。我必须启动和停止服务器,创建和删除 tables.
使用 @Nested 注释,我可以将我的测试分组到嵌套的层次结构中 类,以便每个测试都获得层次结构中所有测试的设置和拆卸。
这种嵌套测试的想法在 Ruby 中得到了普及。 In Java 由 HierarchicalContextRunner 为 Junit 4 实现。请参阅其页面上的理由 https://github.com/bechte/junit-hierarchicalcontextrunner/wiki。
I just don't understand why we need to have nested test class in our
test.
@Nested
组织大型测试 class 确实有意义。
典型用例
很多时候,开发团队通过class定义一个测试class来测试。
这是一个共同的好习惯,但它也可能使您的测试 class 变得非常大,甚至有数百行。您确实可以使用 classes 进行测试,使用多种方法进行测试,每个方法都有多个场景,以及单元测试方法中测试场景所需的一些初始化步骤。
所有这些自然会增加测试class大小。
超过一个阈值(可能是 500 行左右),问问自己是否需要重构就变得合理了。
一个大 class(测试 class 与否),即使组织得很好,也比多个 classes 将具有高 cohesion/relationship 的东西分组更难阅读、维护.
在单元测试用例中,有时情况可能更糟,因为您可能找不到测试场景并在它存在时编写一个新场景,但由于测试 class 很大,您没有设法找到它。
@Nested
: 解决方案
@Nested
通过提供在主(外部)测试 class.
的多个嵌套 class 中分组多个测试方法的可能性来解决这个问题
在主(外部)测试 class 中定义的所有嵌套 classes 的测试方法作为任何测试方法处理。所以 @BeforeEach
、@AfterEach
、@ExtendWith
... 都应用了。
The single exception is @BeforeAll
and @AfterAll
:
Only non-static nested classes (i.e. inner classes) can serve as
@Nested
test classes. Nesting can be arbitrarily deep, and those inner
classes are considered to be full members of the test class family
with one exception: @BeforeAll
and @AfterAll
methods do not work by
default. The reason is that Java does not allow static members in
inner classes. However, this restriction can be circumvented by
annotating a @Nested
test class with
@TestInstance(Lifecycle.PER_CLASS
) (see Test Instance Lifecycle).
结合使用 @Nested
和采用 String
值的 @DisplayName
会变得更好,因为显示名称将用于 IDE 中的测试报告和构建工具并且可能包含空格、特殊字符,甚至表情符号。
示例
我有一个 FooService
有多种方法和多种场景。
我可以在单元测试 class.
的嵌套 classes 中对相同问题的场景进行分组
在这里,我选择测试方法来对它们进行分组(因此我按场景分组),但如果有意义的话,鉴别器可能是另一回事。
例如:
public class FooServiceTest {
Foo foo;
// invoked for ALL test methods
@BeforeEach
public void beforeEach() {
Foo foo = new Foo(...);
}
@Nested
@DisplayName("findWith methods")
class FindMethods {
@Test
void findWith_when_X() throws Exception {
//...
foo.findWith(...);
//...
}
@Test
void findWith_when_Y() throws Exception {
//...
foo.findWith(...);
//...
}
@Test
void findWith_when_Z() throws Exception {
//...
foo.findWith(...);
//...
}
}
@Nested
@DisplayName("findAll methods")
class FindAllMethods {
@Test
void findAll_when_X() throws Exception {
//...
foo.findAll(...);
//...
}
@Test
void findAll_when_Y() throws Exception {
//...
foo.findAll(...);
//...
}
@Test
void findAll_when_Z() throws Exception {
//...
foo.findAll(...);
//...
}
}
@Nested
@DisplayName("computeBar methods")
class ComputeBarMethods {
//...
}
@Nested
@DisplayName("saveOrUpdate methods")
class SaveOrUpdateMethods {
//...
}
}
IDE中的示例效果图
嵌套的子方法默认折叠:
万一或测试失败或按需展开 Nesteds 的子方法:
@Nested - 主要从Junit5开始,提供我们正在尝试做的一个特性的延续逻辑。
将业务测试场景拆分成多个类,@nested正在使用中
在 JUnit 5 中,有一个新的注解:@Nested
。
我明白注释是如何工作的,我明白为什么我们使用嵌套类, 我只是不明白为什么我们需要 嵌套测试 类.
@Nested
注释允许您拥有一个内部 class,它本质上是一个测试 class,允许您将多个测试 class 分组在同一个父项下(具有相同的初始化)。
我所有的测试都需要一个数据库服务器运行。我的大部分测试还需要数据库中的用户 table,才能登录。除此之外,一些测试需要好友 table,才能登录和查询好友。
每个资源都有设置和拆卸。我必须启动和停止服务器,创建和删除 tables.
使用 @Nested 注释,我可以将我的测试分组到嵌套的层次结构中 类,以便每个测试都获得层次结构中所有测试的设置和拆卸。
这种嵌套测试的想法在 Ruby 中得到了普及。 In Java 由 HierarchicalContextRunner 为 Junit 4 实现。请参阅其页面上的理由 https://github.com/bechte/junit-hierarchicalcontextrunner/wiki。
I just don't understand why we need to have nested test class in our test.
@Nested
组织大型测试 class 确实有意义。
典型用例
很多时候,开发团队通过class定义一个测试class来测试。
这是一个共同的好习惯,但它也可能使您的测试 class 变得非常大,甚至有数百行。您确实可以使用 classes 进行测试,使用多种方法进行测试,每个方法都有多个场景,以及单元测试方法中测试场景所需的一些初始化步骤。
所有这些自然会增加测试class大小。
超过一个阈值(可能是 500 行左右),问问自己是否需要重构就变得合理了。
一个大 class(测试 class 与否),即使组织得很好,也比多个 classes 将具有高 cohesion/relationship 的东西分组更难阅读、维护.
在单元测试用例中,有时情况可能更糟,因为您可能找不到测试场景并在它存在时编写一个新场景,但由于测试 class 很大,您没有设法找到它。
@Nested
: 解决方案
@Nested
通过提供在主(外部)测试 class.
的多个嵌套 class 中分组多个测试方法的可能性来解决这个问题
在主(外部)测试 class 中定义的所有嵌套 classes 的测试方法作为任何测试方法处理。所以 @BeforeEach
、@AfterEach
、@ExtendWith
... 都应用了。
The single exception is @BeforeAll
and @AfterAll
:
Only non-static nested classes (i.e. inner classes) can serve as
@Nested
test classes. Nesting can be arbitrarily deep, and those inner classes are considered to be full members of the test class family with one exception:@BeforeAll
and@AfterAll
methods do not work by default. The reason is that Java does not allow static members in inner classes. However, this restriction can be circumvented by annotating a@Nested
test class with@TestInstance(Lifecycle.PER_CLASS
) (see Test Instance Lifecycle).
结合使用 @Nested
和采用 String
值的 @DisplayName
会变得更好,因为显示名称将用于 IDE 中的测试报告和构建工具并且可能包含空格、特殊字符,甚至表情符号。
示例
我有一个 FooService
有多种方法和多种场景。
我可以在单元测试 class.
的嵌套 classes 中对相同问题的场景进行分组
在这里,我选择测试方法来对它们进行分组(因此我按场景分组),但如果有意义的话,鉴别器可能是另一回事。
例如:
public class FooServiceTest {
Foo foo;
// invoked for ALL test methods
@BeforeEach
public void beforeEach() {
Foo foo = new Foo(...);
}
@Nested
@DisplayName("findWith methods")
class FindMethods {
@Test
void findWith_when_X() throws Exception {
//...
foo.findWith(...);
//...
}
@Test
void findWith_when_Y() throws Exception {
//...
foo.findWith(...);
//...
}
@Test
void findWith_when_Z() throws Exception {
//...
foo.findWith(...);
//...
}
}
@Nested
@DisplayName("findAll methods")
class FindAllMethods {
@Test
void findAll_when_X() throws Exception {
//...
foo.findAll(...);
//...
}
@Test
void findAll_when_Y() throws Exception {
//...
foo.findAll(...);
//...
}
@Test
void findAll_when_Z() throws Exception {
//...
foo.findAll(...);
//...
}
}
@Nested
@DisplayName("computeBar methods")
class ComputeBarMethods {
//...
}
@Nested
@DisplayName("saveOrUpdate methods")
class SaveOrUpdateMethods {
//...
}
}
IDE中的示例效果图
嵌套的子方法默认折叠:
万一或测试失败或按需展开 Nesteds 的子方法:
@Nested - 主要从Junit5开始,提供我们正在尝试做的一个特性的延续逻辑。 将业务测试场景拆分成多个类,@nested正在使用中