JUnit 5 @Nested注释的目的是什么?

时间:2016-03-25 13:29:28

标签: java unit-testing junit nested junit5

在JUnit 5中,有一个新的注释:@Nested

我理解它是如何工作的,我理解为什么我们使用嵌套类, 我只是不明白为什么我们需要在测试中使用嵌套测试类。

4 个答案:

答案 0 :(得分:6)

@Nested注释允许您拥有一个本质上是测试类的内部类,允许您在同一个父项下对几个测试类进行分组(具有相同的初始化)。

答案 1 :(得分:1)

我的所有测试都需要运行数据库服务器。我的大多数测试还需要数据库中的Users表才能登录。除此之外,一些测试需要Friends表,才能登录和查询好友。

每个资源都有设置和拆卸。我必须启动和停止服务器,创建和删除表。

使用@Nested注释,我可以在嵌套类的层次结构中对测试进行分组,以便每个测试都能获得层次结构中所有测试的设置和拆除。

这种嵌套测试的想法在Ruby中得到了普及。在Java中由hirarchicalcontextrunner为Junit 4实现。请参阅其https://github.com/bechte/junit-hierarchicalcontextrunner/wiki页上的理由。

答案 2 :(得分:0)

  

我只是不明白为什么我们需要在我们的嵌套测试类中   测试。

@Nested非常适合组织大型测试课程。

典型用例

对于在要测试的类和与之相关联的测试类的数量之间保持1:1映射的开发人员团队(这是一种共享的良好做法),它不需要几个大型测试类,该测试类可以计数数百行模式不好。
实际上,您可以使类具有多种测试方法,每种都有多个场景,以及单元测试方法中测试场景所需的一些初始化步骤。
所有这些自然会增加测试班级的人数。
当超过阈值(可能是500左右)时,问自己是否不需要重构是合理的。

即使是组织良好的大型班级(无论是否经过测试的班级),也比将多个具有较高内聚性/关系的事物进行分组的测试班级更难阅读和维护。
在单元测试的情况下,它可能会更令人讨厌,因为您可能找不到测试场景并在存在新场景的情况下编写了新场景,但是您没有设法在大型测试类中找到它。

@Nested:解决方案

@Nested通过提供在主要测试类的嵌套类中表达几组测试方法之间关系的可能性来解决此问题。
注意,在外部测试类中定义的所有嵌套类的测试方法都将作为外部类测试方法(@BeforeEach@AfterEach@ExtendWith ...)应用于所有测试方法。
The single exception is @BeforeAll and @AfterAll

  

仅非静态嵌套类(即内部类)可以用作   @Nested个测试课程。嵌套可以任意深,而那些内部   类被认为是测试类家族的正式成员   但有一个例外:@BeforeAll@AfterAll方法不适用于   默认。原因是Java不允许使用静态成员   内部阶级。但是,可以通过以下方式来规避此限制   为@Nested测试类添加注释   @TestInstance(Lifecycle.PER_CLASS)(请参阅测试实例生命周期)。

@Nested@DisplayName结合使用,期望String值会变得更好,因为显示名称将用于IDE和构建工具中的测试报告,并且可能包含空格,特殊字符,甚至表情符号

示例

我有一个FooService,具有多种方法和多种方案。 我可以在单元测试课程中对相同关注的场景进行分组。
在这里,我选择了对它们进行分组的测试方法,但如果有意义的话,区分符可能是另一回事。

例如:

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的子方法默认为折叠:

Overview in JUnit Eclipse plugin

万一发生测试失败或失败,您可以展开Nesteds的子方法:

Unfold with a failure in JUnit Eclipse plugin

答案 3 :(得分:0)

@Nested-主要从Junit5开始,提供了我们正在尝试做的功能的延续逻辑。 将业务测试场景分为多个类,使用@nested。