最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用SpringBoot編寫一個(gè)優(yōu)雅的單元測(cè)試

 更新時(shí)間:2023年07月21日 17:03:20   作者:Young丶  
這篇文章主要為大家詳細(xì)介紹了如何使用SpringBoot編寫一個(gè)優(yōu)雅的單元測(cè)試,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下

什么是單元測(cè)試

當(dāng)一個(gè)測(cè)試滿足下面任意一點(diǎn)時(shí),測(cè)試就不是單元測(cè)試 (by Michael Feathers in 2005):

  • 與數(shù)據(jù)庫交流
  • 與網(wǎng)絡(luò)交流
  • 與文件系統(tǒng)交流
  • 不能與其他單元測(cè)試在同一時(shí)間運(yùn)行
  • 不得不為運(yùn)行它而作一些特別的事

如果一個(gè)測(cè)試做了上面的任何一條,那么它就是一個(gè)集成測(cè)試。

不要用 Spring 編寫單元測(cè)試

@SpringBootTest
class OrderServiceTests {
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private OrderService orderService;
    @Test
    void payOrder() {
        Order order = new Order(1L, false);
        orderRepository.save(order);
        Payment payment = orderService.pay(1L, "4532756279624064");
        assertThat(payment.getOrder().isPaid()).isTrue();
        assertThat(payment.getCreditCardNumber()).isEqualTo("4532756279624064");
    }
}

這是一個(gè)單元測(cè)試嗎?首先@SpringBootTest注解加載了整個(gè)應(yīng)用上下文,而僅僅是為了注入兩個(gè) Bean。

另一個(gè)問題是我們需要讀取和寫入訂單到數(shù)據(jù)庫,這也是集成測(cè)試的范疇。

Spring Framework 文檔對(duì)于單元測(cè)試的描述

真正的單元測(cè)試運(yùn)行的非??欤?yàn)椴恍枰\(yùn)行時(shí)去裝配基礎(chǔ)設(shè)施。強(qiáng)調(diào)將真正的單元測(cè)試作為開發(fā)方法的一部分可以提高你的生產(chǎn)力。

編寫 “可單元測(cè)試” 的 Service

Spring Framework 文檔對(duì)于單元測(cè)試的另一描述

依賴注入可以讓你的代碼減少依賴。POJO 可以讓你的應(yīng)用可以通過new操作符在 JUnit 或 TestNG 上進(jìn)行測(cè)試,不需要任何的 Spring 和其他容器

考慮如果編寫這樣的 Service,它方便進(jìn)行單元測(cè)試嗎???

@Service
public class BookService {
    @Autowired
    private BookRepository repository;
    // ... service methods
}

不方便,因?yàn)?code>BookRepository通過@Autowired被注入到 Service 中,并且repository是一個(gè)私有變量,這就限定了外界只能通過 Spring 或其它依賴注入容器(或反射)設(shè)置這個(gè)值,那么單元測(cè)試如果不想加載整個(gè) Spring 容器,那么它就無法使用這個(gè) Service。

而如果這樣寫,使用構(gòu)造方法注入,外界也可以通過new去自行傳遞Repository,這樣即使沒有 Spring,外界也能進(jìn)行快速的測(cè)試。這可能也是 Spring 不推薦屬性注入的原因。

@Service
public class BookService {
    private BookRepository repository;
    @Autowired
    public BookService(BookRepository repository) {
        this.repository = repository;
    }
}

編寫單元測(cè)試

Mockito 介紹

前面的知識(shí)表明,單元測(cè)試就是對(duì)一個(gè)系統(tǒng)中的某個(gè)最小單元的邏輯正確性的測(cè)試,通常是對(duì)一個(gè)方法來進(jìn)行測(cè)試,因?yàn)橹粶y(cè)試邏輯正確性,所以這個(gè)測(cè)試是獨(dú)立的,不與任何外界環(huán)境相關(guān),比如不需要連接數(shù)據(jù)庫,不訪問網(wǎng)絡(luò)和文件系統(tǒng),不依賴其他單元測(cè)試。但是現(xiàn)實(shí)的業(yè)務(wù)邏輯中往往有很多復(fù)雜錯(cuò)綜的依賴關(guān)系,比如你想對(duì) Service 進(jìn)行單元測(cè)試,那么它要依賴一個(gè)數(shù)據(jù)庫持久層的 Repository 對(duì)象,這時(shí)候就難辦了,若創(chuàng)建了一個(gè) Repository 便連接了數(shù)據(jù)庫,連接了數(shù)據(jù)庫便不是一個(gè)獨(dú)立的單元測(cè)試。

Mockito 是一個(gè)用來在單元測(cè)試中快速模擬那些需要與外界環(huán)境溝通的對(duì)象,以便我們快速的、方便的進(jìn)行單元測(cè)試而不用啟動(dòng)整個(gè)系統(tǒng)。

下面的代碼就是 Mockito 的一個(gè)基礎(chǔ)使用,Mock 意為偽造。

// 通過mock方法偽造一個(gè)orderRepository的實(shí)現(xiàn),這個(gè)實(shí)現(xiàn)目前什么都不會(huì)做
orderRepository = mock(OrderRepository.class);
// 通過mock方法偽造一個(gè)paymentRepository的實(shí)現(xiàn),這個(gè)實(shí)現(xiàn)目前什么都不會(huì)做
paymentRepository = mock(PaymentRepository.class)
// 創(chuàng)建一個(gè)Order對(duì)象以便一會(huì)兒使用
Order order = new Order(1L, false);
// 使用when方法,定義當(dāng)orderRepository.findById(1L)被調(diào)用時(shí)的行為,直接返回剛剛創(chuàng)建的order對(duì)象
when(orderRepository.findById(1L)).thenReturn(Optional.of(order));
// 使用when方法,定義當(dāng)paymentRepository.save(任何參數(shù))被調(diào)用時(shí)的行為,直接返回傳入的參數(shù)。
when(paymentRepository.save(any())).then(returnsFirstArg());

單元測(cè)試

class OrderServiceTests {
    private OrderRepository orderRepository;
    private PaymentRepository paymentRepository;
    private OrderService orderService;
    @BeforeEach
    void setupService() {
        orderRepository = mock(OrderRepository.class);
        paymentRepository = mock(PaymentRepository.class);
        orderService = new OrderService(orderRepository, paymentRepository);
    }
    @Test
    void payOrder() {
        Order order = new Order(1L, false);
        when(orderRepository.findById(1L)).thenReturn(Optional.of(order));
        when(paymentRepository.save(any())).then(returnsFirstArg());
        Payment payment = orderService.pay(1L, "4532756279624064");
        assertThat(payment.getOrder().isPaid()).isTrue();
        assertThat(payment.getCreditCardNumber()).isEqualTo("4532756279624064");
    }
}

現(xiàn)在我們即使不想連接數(shù)據(jù)庫,也可以通過mock來給定一個(gè) Repository 的其他實(shí)現(xiàn),這樣這個(gè)方法可以在毫秒內(nèi)完成。

也可以使用Mockito

@ExtendWith(MockitoExtension.class)
class OrderServiceTests {
    @Mock
    private OrderRepository orderRepository;
    @Mock
    private PaymentRepository paymentRepository;
    @InjectMocks
    private OrderService orderService;
    // ...
}

以上就是使用SpringBoot編寫一個(gè)優(yōu)雅的單元測(cè)試的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot單元測(cè)試的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java教學(xué)筆記之對(duì)象的創(chuàng)建與銷毀

    java教學(xué)筆記之對(duì)象的創(chuàng)建與銷毀

    面向?qū)ο蟮木幊陶Z言使程序能夠直觀的反應(yīng)客觀世界的本來面目,并且使軟件開發(fā)人員能夠運(yùn)用人類認(rèn)識(shí)事物所采用的一般思維方法進(jìn)行軟件開發(fā),是當(dāng)今計(jì)算機(jī)領(lǐng)域中軟件開發(fā)和應(yīng)用的主流技術(shù)。
    2016-01-01
  • Mybatis的核心配置文件使用方法

    Mybatis的核心配置文件使用方法

    Mybatis的核心配置文件有兩個(gè),一個(gè)是全局配置文件,它包含了會(huì)深深影響Mybatis行為的設(shè)置和屬性信息;一個(gè)是映射文件,它很簡(jiǎn)單,讓用戶能更專注于SQL代碼,本文主要介紹了Mybatis的核心配置文件使用方法,感興趣的可以了解一下
    2023-11-11
  • 解決SpringBoot在IDEA中熱部署失效問題

    解決SpringBoot在IDEA中熱部署失效問題

    熱部署是指程序運(yùn)行過程中實(shí)時(shí)更新或替換其組件的技術(shù),即項(xiàng)目正在啟動(dòng)中,修改了配置文件中某個(gè)值或者添加了某個(gè)方法或者修改了某個(gè)方法參數(shù),本文給大家介紹了解決SpringBoot在IDEA中熱部署失效問題,需要的朋友可以參考下
    2024-01-01
  • Java實(shí)現(xiàn)簡(jiǎn)單猜數(shù)字小游戲

    Java實(shí)現(xiàn)簡(jiǎn)單猜數(shù)字小游戲

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)猜數(shù)字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • 使用maven創(chuàng)建普通項(xiàng)目命令行程序詳解

    使用maven創(chuàng)建普通項(xiàng)目命令行程序詳解

    大部分使用maven創(chuàng)建的是web項(xiàng)目,這里使用maven創(chuàng)建一個(gè)命令行程序,目的是讓大家了解maven特點(diǎn)和使用方式,有需要的朋友可以借鑒參考下
    2021-10-10
  • 一文詳解Java中的JSON數(shù)據(jù)處理指南

    一文詳解Java中的JSON數(shù)據(jù)處理指南

    JSON作為一種輕量級(jí)的數(shù)據(jù)交換格式,在Web服務(wù)和應(yīng)用程序之間廣泛使用,本文詳細(xì)介紹了在Java中解析和操作JSON數(shù)據(jù)的步驟,包括導(dǎo)入庫、創(chuàng)建JSON對(duì)象和數(shù)組、讀取數(shù)據(jù)、創(chuàng)建和序列化JSON對(duì)象,以及錯(cuò)誤處理等,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • Springmvc實(shí)現(xiàn)文件下載2種實(shí)現(xiàn)方法

    Springmvc實(shí)現(xiàn)文件下載2種實(shí)現(xiàn)方法

    這篇文章主要介紹了Springmvc實(shí)現(xiàn)文件下載2種實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • java實(shí)現(xiàn)微信點(diǎn)餐申請(qǐng)微信退款

    java實(shí)現(xiàn)微信點(diǎn)餐申請(qǐng)微信退款

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)微信點(diǎn)餐申請(qǐng)微信退款,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • SpringBoot2.x 集成 Thymeleaf的詳細(xì)教程

    SpringBoot2.x 集成 Thymeleaf的詳細(xì)教程

    本文主要對(duì)SpringBoot2.x集成Thymeleaf及其常用語法進(jìn)行簡(jiǎn)單總結(jié),其中SpringBoot使用的2.4.5版本。對(duì)SpringBoot2.x 集成 Thymeleaf知識(shí)感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • Spring超詳細(xì)講解事務(wù)和事務(wù)傳播機(jī)制

    Spring超詳細(xì)講解事務(wù)和事務(wù)傳播機(jī)制

    Spring事務(wù)的本質(zhì)就是對(duì)數(shù)據(jù)庫事務(wù)的支持,沒有數(shù)據(jù)庫事務(wù),Spring是無法提供事務(wù)功能的。Spring只提供統(tǒng)一的事務(wù)管理接口,具體實(shí)現(xiàn)都是由數(shù)據(jù)庫自己實(shí)現(xiàn)的,Spring會(huì)在事務(wù)開始時(shí),根據(jù)當(dāng)前設(shè)置的隔離級(jí)別,調(diào)整數(shù)據(jù)庫的隔離級(jí)別,由此保持一致
    2022-06-06

最新評(píng)論

长治县| 浦县| 四会市| 黎川县| 娱乐| 天镇县| 且末县| 吉木乃县| 芦溪县| 东城区| 万年县| 江油市| 花垣县| 彭水| 遂宁市| 嘉峪关市| 万源市| 鸡东县| 呼和浩特市| 砚山县| 图们市| 玉龙| 休宁县| 京山县| 隆尧县| 上蔡县| 桑日县| 芜湖县| 荆州市| 方城县| 长顺县| 津南区| 商都县| 肥乡县| 左云县| 延边| 游戏| 长春市| 徐水县| 鹤庆县| 普安县|