返回

利用JUnit、AssertJ和Mockito编写单元测试,探索敏捷开发之道(十三)

开发工具

在单元测试的实践中,我们通常会遇到这样的场景:多个测试方法需要对被测类进行相同的准备工作,例如创建对象、设置属性等。这些重复性的代码不仅会降低测试效率,还会增加维护难度。为了解决这个问题,我们可以引入"生命周期方法"来简化测试过程。

在JUnit中,"生命周期方法"是指那些在测试用例执行前后自动调用的方法。这些方法通常用于准备测试环境、创建被测类实例、清理测试资源等。通过合理地运用"生命周期方法",我们可以将重复性的代码移出测试方法,从而提高测试的可读性、可维护性和可重用性。

其中,最常用的"生命周期方法"包括:

  • @BeforeClass:在所有测试方法之前执行一次。
  • @AfterClass:在所有测试方法执行完毕后执行一次。
  • @Before:在每个测试方法之前执行一次。
  • @After:在每个测试方法执行完毕后执行一次。

下面,我们就以一个具体的例子来演示如何使用"生命周期方法"来消除测试方法之间的重复代码。

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

class MyServiceTest {

    private MyService service;

    @BeforeAll
    static void setUpClass() {
        // 在所有测试方法之前执行一次
        // 通常用于初始化静态资源或执行一些一次性的操作
    }

    @BeforeEach
    void setUp() {
        // 在每个测试方法之前执行一次
        // 通常用于创建被测类实例或进行其他测试准备工作
        service = new MyService();
    }

    @Test
    void testMethod1() {
        // 测试方法1
        // 调用service的方法进行测试
        assertThat(service.calculateSomething()).isEqualTo(10);
    }

    @Test
    void testMethod2() {
        // 测试方法2
        // 调用service的方法进行测试
        assertThat(service.calculateSomethingElse()).isEqualTo(20);
    }

    @AfterEach
    void tearDown() {
        // 在每个测试方法执行完毕后执行一次
        // 通常用于清理测试资源或进行其他测试收尾工作
        service = null;
    }

    @AfterClass
    static void tearDownClass() {
        // 在所有测试方法执行完毕后执行一次
        // 通常用于释放静态资源或执行一些一次性的收尾操作
    }
}

在这个例子中,我们使用了@BeforeAll@BeforeEach@AfterEach@AfterClass这四个"生命周期方法"来优化测试代码。

  • @BeforeAll方法在所有测试方法之前执行一次,我们在这里初始化了一些静态资源。
  • @BeforeEach方法在每个测试方法之前执行一次,我们在这里创建了被测类MyService的实例。
  • @AfterEach方法在每个测试方法执行完毕后执行一次,我们在这里清理了测试资源,将service变量设置为null
  • @AfterClass方法在所有测试方法执行完毕后执行一次,我们在这里释放了静态资源。

通过使用"生命周期方法",我们消除了测试方法1和测试方法2之间的重复代码,使测试代码更加简洁、可读和易于维护。

除了上面的例子,"生命周期方法"还有很多其他应用场景。例如,我们可以使用@BeforeClass方法来创建数据库连接,然后在@AfterClass方法中关闭数据库连接。或者,我们可以使用@BeforeEach方法来加载测试数据,然后在@AfterEach方法中清除测试数据。

总之,"生命周期方法"是一个非常实用的工具,可以帮助我们编写更简洁、可读和可维护的单元测试。通过合理地运用"生命周期方法",我们可以提高测试效率,降低维护难度,从而编写出高质量的单元测试。