Spring Boot單元測試詳解

一、JUnit5與Spring Boot Test

Spring Boot Test 是 Spring Boot 提供的測試框架,用於簡化單元測試的編寫過程。Spring Boot Test整合了許多JUnit5的特性,比如@ExtendWith,@Test,@Nested等。使用Spring Boot Test,我們可以做到“無環境”單元測試,即在不需要外部環境支持的情況下進行測試。

在使用Spring Boot Test時,需要引入spring-boot-starter-test依賴,如下:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

對於單元測試,可以使用@SpringBootTest註解,表示加載整個Spring應用上下文。@SpringBootTest使用隨機端口啟動應用程序,可以使用@LocalServerPort註解注入隨機端口值。

    @SpringBootTest
    public class MyTest {

        @LocalServerPort
        private int port;

        private static final String URL_PREFIX = "http://localhost:";

        @Test
        public void test(){
            RestTemplate restTemplate = new RestTemplate();
            String result = restTemplate.getForObject(URL_PREFIX + port + "/hello", String.class);
            Assertions.assertEquals("hello", result);
        }
    }

二、Mockito進行依賴的Mock與Stub

Mockito是一個用於Java應用程序的單元測試框架,主要用於對依賴進行Mock或Stub。Mock指的是一個對象,並且根據需要返回預定義的輸出。Stub指的是一個對象,如果根據需要返回預定義的輸出,則執行代碼的默認實現。

Mockito可以通過Mockito.mock()創建Mock對象。Mock對象只是一個空殼,它不會執行代碼的默認實現,只會返回預先設置的值。Mockito使用when().thenReturn()設置預期返回值。

    public class MyTest {
        @Test
        public void test(){
            //創建Mock對象
            MyDAO myDaoMock = Mockito.mock(MyDAO.class);

            //設置預期返回值
            when(myDaoMock.getDataById(1)).thenReturn("data1");

            //調用被測方法,並驗證返回值是否符合預期
            MyService myService = new MyService(myDaoMock);
            String result = myService.getDataById(1);
            Assertions.assertEquals("data1", result);

            //驗證是否已經調用MyDAO的getDataById方法
            verify(myDaoMock, times(1)).getDataById(1);
        }
    }

三、Testcontainers進行外部環境的集成測試

Testcontainers是一個Java庫,可在本地或CI環境中運行Docker容器進行測試,用於進行外部環境的集成測試。

Testcontainers可與JUnit5和Spring Boot Test一起使用,只需在測試類中添加@Container和@DynamicPropertySource註解即可。@Container指示Testcontainers在測試之前運行Docker容器,@DynamicPropertySource則指定將動態分配的端口自動配置為Spring Boot 的配置文件中的屬性。

    @SpringBootTest
    @ExtendWith(SpringExtension.class)
    @Testcontainers
    public class MyTest {

        @Container
        private static final MySQLContainer mysqlContainer = new MySQLContainer();

        @DynamicPropertySource
        static void mysqlProperties(DynamicPropertyRegistry registry) {
            registry.add("spring.datasource.url", mysqlContainer::getJdbcUrl);
            registry.add("spring.datasource.username", mysqlContainer::getUsername);
            registry.add("spring.datasource.password", mysqlContainer::getPassword);
        }

        @Autowired
        private MyRepository myRepository;
        
        @Test
        public void test(){
            //測試代碼
        }
    }

四、WebFlux測試

Spring Framework 5中引入的WebFlux是一種非阻塞、反應式編程風格的Web框架。對於WebFlux測試,可以使用spring-test庫中的webTestClient實現。

webTestClient可以很容易地創建並發送請求,接收響應,並進行斷言。webTestClient從中獲得響應的Mono對象,可以通過subscribe方法阻塞響應。

    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    @AutoConfigureWebTestClient
    public class MyTest {

        @Autowired
        private WebTestClient webTestClient;

        @Test
        public void test(){
            String result = webTestClient.get().uri("/hello")
                    .exchange().expectStatus().isOk()
                    .returnResult(String.class).getResponseBody().blockFirst();
            Assertions.assertEquals("hello", result);
        }
    }

五、小結

Spring Boot Test是便於編寫和執行測試用例的框架,支持單元測試、集成測試和WebFlux測試。Mockito用於測試中對依賴進行Mock或Stub,通過對依賴的預設行為,達到對實際業務場景的模擬測試。Testcontainers可以方便地測試運行在Docker容器中的外部環境,使測試用例更接近於實際生產環境。WebFlux基於異步非阻塞的編程模型,WebTestClient提供了對WebFlux應用的便捷測試支持。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/160878.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-21 01:15
下一篇 2024-11-21 01:15

相關推薦

發表回復

登錄後才能評論