嵌套的测试

重要性:★★★☆☆

有时候一个测试类中的测试方法太多,有必要根据内聚性原则将它们分组。

可以在测试类的内部定义嵌套内类(不能是静态内类)并注解为@Nested将测试进行分组。在顶层类和嵌套类中都可以定义测试方法和生命周期方法。

嵌套的层级数量没有限制。

如果测试生命周期是PER_METHOD的,嵌套类不允许定义@BeforeAll@AfterAll生命周期方法。如果测试生命周期是PER_CLASS的,嵌套类中可以定义@BeforeAll@AfterAll生命周期方法。

如果外层测试类中有定义@BeforeEach@AfterEach生命周期方法,那么它们也会在嵌套类的每个测试方法前后执行一次。

示例代码如下:

package yang.yu.tdd.nested;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.EmptyStackException;
import java.util.Stack;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

@DisplayName("A stack")
class TestingAStackDemo {

    Stack<Object> stack;

    @Test
    @DisplayName("is instantiated with new Stack()")
    void isInstantiatedWithNew() {
        new Stack<>();
    }

    @Nested
    @DisplayName("when new")
    class WhenNew {

        @BeforeEach
        void createNewStack() {
            stack = new Stack<>();
        }

        @Test
        @DisplayName("is empty")
        void isEmpty() {
            assertTrue(stack.isEmpty());
        }

        @Test
        @DisplayName("throws EmptyStackException when popped")
        void throwsExceptionWhenPopped() {
            assertThrows(EmptyStackException.class, stack::pop);
        }

        @Test
        @DisplayName("throws EmptyStackException when peeked")
        void throwsExceptionWhenPeeked() {
            assertThrows(EmptyStackException.class, stack::peek);
        }

        @Nested
        @DisplayName("after pushing an element")
        class AfterPushing {

            String anElement = "an element";

            @BeforeEach
            void pushAnElement() {
                stack.push(anElement);
            }

            @Test
            @DisplayName("it is no longer empty")
            void isNotEmpty() {
                assertFalse(stack.isEmpty());
            }

            @Test
            @DisplayName("returns the element when popped and is empty")
            void returnElementWhenPopped() {
                assertEquals(anElement, stack.pop());
                assertTrue(stack.isEmpty());
            }

            @Test
            @DisplayName("returns the element when peeked but remains not empty")
            void returnElementWhenPeeked() {
                assertEquals(anElement, stack.peek());
                assertFalse(stack.isEmpty());
            }
        }
    }
}

执行测试结果显示如下,可见输出也是层级化的:

nested-tests

一种可行的组织测试代码的方式是:为每个被测试的产品类创建一个对应的测试类。在测试类内部,针对被测类的每个工作单元(一般是方法)分别创建一个注解为@Nested的嵌套类,包含针对这个工作单元的所有测试。

results matching ""

    No results matching ""