banner
biuaxia

biuaxia

"万物皆有裂痕,那是光进来的地方。"
github
bilibili
tg_channel

在SpringBoot中使用JUnit進行代碼測試

title: 在 SpringBoot 中使用 JUnit 進行代碼測試
date: 2021-08-24 15:30:00
toc: true
category:

  • Java
    tags:
  • Java
  • SpringBoot
  • 單元
  • 測試

Junit 是 Java 知名的測試框架,通過集成 Junit + SpringBoot Test 可以在測試程序中使用 SpringBoot 的依賴注入等 SpringBoot 特性。

依賴#

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

測試 Service#

位置:src/main/java/com/example/service/impl/HelloServiceImpl.java

package com.example.service.impl;

@Service
public class HelloServiceImpl implements HelloService {

    @Override
    public String helloTo(String name) {
        // 故意寫一個 Bug
        if ("C++".equals(name))
            return "不要對 C++ 打招呼";
        return StringUtils.hasText(name) ? "HELLO " + name : "HELLO WORLD";
    }
}

想要測試這一段代碼,Java 通用的方式是自己 new 出所需的資源,再進行測試使用,但這樣的話就無法使用 SpringBoot 的各種特性了,如果需要的依賴特別多,或者是牽扯到各種配置讀取的話,簡直就是噩夢:

private HelloService helloService;

@Before
public void setUp() {
    helloService = new HelloService();
}

@Test
public void helloTo() {
    assertEquals("HELLO WORLD", helloService.helloTo(""));
    assertEquals("HELLO WORLD", helloService.helloTo("WORLD"));
    assertEquals("HELLO JAVA", helloService.helloTo("JAVA"));
    assertEquals("HELLO C++", helloService.helloTo("C++")); // 出錯
}

方法一:注解啟動 SpringBoot#

位置:src/test/java/com/example/service/impl/HelloServiceImplTest.java

重點:

  • 使用 Junit SpringBoot Test 框架:@RunWith(SpringRunner.class)
  • 指定啟動入口:@SpringBootTest(classes = [SpringBoot 程序入口類])

在測試結束之後,SpringBoot 上下文會自動關閉。

package com.example.service.impl;

import com.example.SpringBootTestApplication;
import com.example.service.HelloService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import static org.junit.Assert.*;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootTestApplication.class)
public class HelloServiceImplTest {

    @Autowired
    private HelloService helloService;

    @Test
    public void helloTo() {
        assertEquals("HELLO WORLD", helloService.helloTo(""));
        assertEquals("HELLO WORLD", helloService.helloTo("WORLD"));
        assertEquals("HELLO JAVA", helloService.helloTo("JAVA"));
        assertEquals("HELLO C++", helloService.helloTo("C++")); // 出錯
    }
}

方法二:顯式啟動 SpringBoot#

通過使用 SpringApplication::run 方法來啟動 SpringBoot 程序,也可以做到使用 SpringBoot 所有特性來進行測試,但稍微麻煩了些,而且必須在測試結束之後手動對 SpringBootContext 進行關閉。

package com.example.service.impl;

import com.example.SpringBootTestApplication;
import com.example.service.HelloService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;

import static org.junit.Assert.assertEquals;

public class HelloServiceImplTest2 {

    private ConfigurableApplicationContext context;
    private HelloService helloService;

    @Before
    public void setUp() {
        context = SpringApplication.run(SpringBootTestApplication.class);
        // 顯式獲取 Bean,所需依賴 SpringBoot 會自動注入
        helloService = context.getBean(HelloService.class);
    }

    @After
    public void tearDown() {
        // 關閉 SpringBoot 程序
        context.close();
    }

    @Test
    public void helloTo() {
        assertEquals("HELLO WORLD", helloService.helloTo(""));
        assertEquals("HELLO WORLD", helloService.helloTo("WORLD"));
        assertEquals("HELLO JAVA", helloService.helloTo("JAVA"));
        assertEquals("HELLO C++", helloService.helloTo("C++")); // 出錯
    }
}
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。