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

SpringBoot中Mockito單元測(cè)試入門(mén)

 更新時(shí)間:2021年06月01日 10:34:12   作者:小小工匠  
單元測(cè)試在很多地方都用的到,本文主要介紹了SpringBoot中Mockito單元測(cè)試入門(mén),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

Mock 測(cè)試

Mock 測(cè)試就是在測(cè)試過(guò)程中,創(chuàng)建一個(gè)假的對(duì)象,避免你為了測(cè)試一個(gè)方法,卻要自行構(gòu)建整個(gè) Bean 的依賴(lài)鏈。

舉個(gè)例子:

類(lèi) A 需要調(diào)用類(lèi) B 和類(lèi) C,而類(lèi) B 和類(lèi) C 又需要調(diào)用其他類(lèi)如 D、E、F 等,假設(shè)類(lèi) D 是一個(gè)外部服務(wù),那就會(huì)很難測(cè),因?yàn)槟愕姆祷亟Y(jié)果會(huì)直接的受外部服務(wù)影響,導(dǎo)致你的單元測(cè)試可能今天會(huì)過(guò)、但明天就過(guò)不了了。

在這里插入圖片描述

而當(dāng)我們引入 Mock 測(cè)試時(shí),就可以創(chuàng)建一個(gè)假的對(duì)象,替換掉真實(shí)的 Bean B 和 C,這樣在調(diào)用B、C的方法時(shí),實(shí)際上就會(huì)去調(diào)用這個(gè)假的 Mock 對(duì)象的方法,而我們就可以自己設(shè)定這個(gè) Mock 對(duì)象的參數(shù)和期望結(jié)果,讓我們可以專(zhuān)注在測(cè)試當(dāng)前的類(lèi) A,而不會(huì)受到其他的外部服務(wù)影響,這樣測(cè)試效率就能提高很多。

在這里插入圖片描述

What's Mockito

Mockito 是一種 Java Mock 框架,主要就是用來(lái)做 Mock 測(cè)試的,它可以模擬任何 Spring 管理的 Bean、模擬方法的返回值、模擬拋出異常等等,同時(shí)也會(huì)記錄調(diào)用這些模擬方法的參數(shù)、調(diào)用順序,從而可以校驗(yàn)出這個(gè) Mock 對(duì)象是否有被正確的順序調(diào)用,以及按照期望的參數(shù)被調(diào)用。

像是 Mockito 可以在單元測(cè)試中模擬一個(gè) Service 返回的數(shù)據(jù),而不會(huì)真正去調(diào)用該 Service,通過(guò)模擬一個(gè)假的 Service 對(duì)象,來(lái)快速的測(cè)試當(dāng)前想要測(cè)試的類(lèi)。

目前在 Java 中主流的 Mock 測(cè)試工具有 Mockito、JMock、EasyMock等等,而 SpringBoot 目前默認(rèn)的測(cè)試框架是 Mockito 框架。

使用 Mockito

pom依賴(lài)

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

在這里插入圖片描述

Demo Code

一個(gè) UserService,兩個(gè)方法

  • getUserById() -------------> 調(diào)用 UserDao 這個(gè) bean的 getUserById()
  • insertUser() -------------> 調(diào)用 UserDao 這個(gè) bean的 insertUser()
@Component
public class UserService {
    
    @Autowired
    private UserDao userDao;

    public User getUserById(Integer id) {
        return userDao.getUserById(id);
    }

    public Integer insertUser(User user) {
        return userDao.insertUser(user);
    }
}

【POJO對(duì)象】

public class User {
    private Integer id;
    private String name;
    //省略 getter/setter
}

【常規(guī)操作】

如果這時(shí)候我們先不使用 Mockito 模擬一個(gè)假的 userDao Bean,而是真的去調(diào)用一個(gè)正常的 Spring Bean 的 userDao 的話, 注入 userService Bean,然后去調(diào)用方法,而他會(huì)再去調(diào)用 userDao 取得數(shù)據(jù)庫(kù)的數(shù)據(jù),然后我們?cè)賹?duì)返回結(jié)果做 Assert 斷言檢查。

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {

    //先普通的注入一個(gè)userService bean
    @Autowired
    private UserService userService;

    @Test
    public void getUserById() throws Exception {
        //普通的使用userService,他里面會(huì)再去調(diào)用userDao取得數(shù)據(jù)庫(kù)的數(shù)據(jù)
        User user = userService.getUserById(1);
        
        //檢查結(jié)果
        Assert.assertNotNull(user);
        Assert.assertEquals(user.getId(), new Integer(1));
        Assert.assertEquals(user.getName(), "John");
    }
}

【Mockito】

但是如果 userDao 還沒(méi)寫(xiě)好,又想先測(cè) userService 的話,就需要使用 Mockito 去模擬一個(gè)假的 userDao 出來(lái)。

具體怎么搞呢?

在 userDao 上加上一個(gè) @MockBean 注解

當(dāng) userDao 被加上這個(gè)注解之后,表示 Mockito 會(huì)幫我們創(chuàng)建一個(gè)假的 Mock 對(duì)象,替換掉 Spring 中已存在的那個(gè)真實(shí)的 userDao Bean,也就是說(shuō),注入進(jìn) userService 的 userDao Bean,已經(jīng)被我們替換成假的 Mock 對(duì)象了,所以當(dāng)我們?cè)俅握{(diào)用 userService 的方法時(shí),會(huì)去調(diào)用的實(shí)際上是 mock userDao Bean 的方法,而不是真實(shí)的 userDao Bean。

當(dāng)我們創(chuàng)建了一個(gè)假的 userDao 后,我們需要為這個(gè) mock userDao 自定義方法的返回值,這里有一個(gè)公式用法,下面這段代碼的意思為,當(dāng)調(diào)用了某個(gè) Mock 對(duì)象的方法時(shí),就回傳我們想要的自定義結(jié)果。

Mockito.when( 對(duì)象.方法名() ).thenReturn( 自定義結(jié)果 )

代碼如下:

@RunWith(SpringRunner.class)
@SpringBootTest
publicclass UserServiceTest {
    
    @Autowired
    private UserService userService;
    
    @MockBean
    private UserDao userDao;

    @Test
    public void getUserById() throws Exception {
        // 定義當(dāng)調(diào)用mock userDao的getUserById()方法,并且參數(shù)為3時(shí),就返回id為200、name為I'm mock3的user對(duì)象
        Mockito.when(userDao.getUserById(3)).thenReturn(new User(200, "Aritisan"));
        
        // 返回的會(huì)是名字為I'm mock 3的user對(duì)象
        User user = userService.getUserById(1);

        Assert.assertNotNull(user);
        Assert.assertEquals(user.getId(), new Integer(200));
        Assert.assertEquals(user.getName(), "Aritisan");
    }
}

Mockito 除了最基本的 Mockito.when( 對(duì)象.方法名() ).thenReturn( 自定義結(jié)果 ),還提供了其他用法讓我們使用。

thenReturn

當(dāng)使用任何整數(shù)值調(diào)用 userService 的 getUserById() 方法時(shí),就回傳一個(gè)名字為Aritisan的 User 對(duì)象。

Mockito.when(userService.getUserById(Mockito.anyInt())).thenReturn(new User(3, "Aritisan"));
User user1 = userService.getUserById(3); // 回傳的user的名字為Aritisan
User user2 = userService.getUserById(200); // 回傳的user的名字也為Aritisan

限制只有當(dāng)參數(shù)的數(shù)字是 3 時(shí),才會(huì)回傳名字為 Aritisan 的 user 對(duì)象。

Mockito.when(userService.getUserById(3)).thenReturn(new User(3, "Aritisan"));
User user1 = userService.getUserById(3); // 回傳的user的名字為Aritisan
User user2 = userService.getUserById(200); // 回傳的user為null

當(dāng)調(diào)用 userService 的 insertUser() 方法時(shí),不管傳進(jìn)來(lái)的 user 是什么,都回傳 100。

Mockito.when(userService.insertUser(Mockito.any(User.class))).thenReturn(100);
Integer i = userService.insertUser(new User()); //會(huì)返回100

thenThrow

當(dāng)調(diào)用 userService 的 getUserById() 時(shí)的參數(shù)是 9 時(shí),拋出一個(gè) RuntimeException。

Mockito.when(userService.getUserById(9)).thenThrow(new RuntimeException("mock throw exception"));
User user = userService.getUserById(9); //會(huì)拋出一個(gè)RuntimeException

如果方法沒(méi)有返回值的話(即是方法定義為 public void myMethod() {…}),要改用 doThrow() 拋出 Exception。

Mockito.doThrow(new RuntimeException("mock throw  exception")).when(userService).print();
userService.print(); //會(huì)拋出一個(gè)RuntimeException

verify

檢查調(diào)用 userService 的 getUserById()、且參數(shù)為3的次數(shù)是否為1次。

驗(yàn)證調(diào)用順序,驗(yàn)證 userService 是否先調(diào)用 getUserById() 兩次,并且第一次的參數(shù)是 3、第二次的參數(shù)是 5,然后才調(diào)用insertUser() 方法。

InOrder inOrder = Mockito.inOrder(userService);
inOrder.verify(userService).getUserById(3);
inOrder.verify(userService).getUserById(5);
inOrder.verify(userService).insertUser(Mockito.any(User.class));

Mockito 注意事項(xiàng)

上述就是 Mockito 的 Mock 對(duì)象使用方法,不過(guò)當(dāng)使用 Mockito 在 Mock 對(duì)象時(shí),有一些限制需要遵守:

  • 不能 Mock 靜態(tài)方法
  • 不能 Mock private 方法
  • 不能 Mock final class

因此在寫(xiě)代碼時(shí),需要做良好的功能拆分,才能夠使用 Mockito 的 Mock 技術(shù),幫助我們降低測(cè)試時(shí) Bean 的耦合度。

到此這篇關(guān)于SpringBoot中Mockito單元測(cè)試入門(mén)的文章就介紹到這了,更多相關(guān)SpringBoot Mockito單元測(cè)試 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決JDK版本沖突顯示問(wèn)題(雙版本沖突)

    解決JDK版本沖突顯示問(wèn)題(雙版本沖突)

    這篇文章主要介紹了解決JDK版本沖突顯示問(wèn)題(雙版本沖突),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • DispatcherServlet處理器的適配和處理解析

    DispatcherServlet處理器的適配和處理解析

    這篇文章主要為大家介紹了DispatcherServlet的處理器的適配和處理流程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • 基于Failed?to?load?ApplicationContext異常的解決思路

    基于Failed?to?load?ApplicationContext異常的解決思路

    這篇文章主要介紹了基于Failed?to?load?ApplicationContext異常的解決思路,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java實(shí)現(xiàn)線程的暫停和恢復(fù)的示例詳解

    Java實(shí)現(xiàn)線程的暫停和恢復(fù)的示例詳解

    這幾天的項(xiàng)目中,客戶給了個(gè)需求,希望我可以開(kāi)啟一個(gè)任務(wù),想什么時(shí)候暫停就什么時(shí)候暫停,想什么時(shí)候開(kāi)始就什么時(shí)候開(kāi)始,所以本文小編給大家介紹了Java實(shí)現(xiàn)線程的暫停和恢復(fù)的示例,需要的朋友可以參考下
    2023-11-11
  • SpringMVC中的@RequestMapping注解解析

    SpringMVC中的@RequestMapping注解解析

    這篇文章主要介紹了SpringMVC中的@RequestMapping注解解析,SpringMVC使用@RequestMapping注解為控制器指定可以處理哪些?URL?請(qǐng)求,在控制器的類(lèi)定義及方法定義處都可標(biāo)注@RequestMapping,需要的朋友可以參考下
    2023-12-12
  • springboot后端解決跨域問(wèn)題

    springboot后端解決跨域問(wèn)題

    今天小編就為大家分享一篇關(guān)于springboot后端解決跨域問(wèn)題,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • JAVA ArrayList詳細(xì)介紹(示例)

    JAVA ArrayList詳細(xì)介紹(示例)

    本文對(duì)JAVA ArrayList做了詳細(xì)介紹,文中學(xué)到了ArrayList源碼解析、ArrayList遍歷方式、toArray()異常,最后給出了ArrayList示例。
    2013-11-11
  • springboot打成jar后獲取classpath下文件失敗的解決方案

    springboot打成jar后獲取classpath下文件失敗的解決方案

    這篇文章主要介紹了使用springboot打成jar后獲取classpath下文件失敗的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • IDEA標(biāo)簽tabs多行顯示的設(shè)置

    IDEA標(biāo)簽tabs多行顯示的設(shè)置

    這篇文章主要介紹了IDEA標(biāo)簽tabs多行顯示的設(shè)置方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • SpringMVC mybatis整合實(shí)例代碼詳解

    SpringMVC mybatis整合實(shí)例代碼詳解

    這篇文章主要介紹了springmvc與mybatis實(shí)例詳解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-04-04

最新評(píng)論

金山区| 中牟县| 崇左市| 渝北区| 全南县| 鸡东县| 天峨县| 延川县| 三都| 宁阳县| 钟祥市| 延津县| 奉节县| 新宁县| 潍坊市| 江都市| 岗巴县| 钦州市| 建宁县| 永胜县| 西峡县| 大悟县| 临潭县| 青海省| 闵行区| 民勤县| 东安县| 南华县| 阿克陶县| 中西区| 吴川市| 眉山市| 东城区| 丹阳市| 峨眉山市| 介休市| 福建省| 同德县| 乌拉特中旗| 东光县| 台南县|