国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Service層代碼單元測(cè)試以及單元測(cè)試如何Mock

這篇具有很好參考價(jià)值的文章主要介紹了Service層代碼單元測(cè)試以及單元測(cè)試如何Mock。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、背景

接著上一篇文章:?jiǎn)卧獪y(cè)試入門篇,本篇文章作為單元測(cè)試的進(jìn)階篇,主要介紹如何對(duì)Springboot Service層代碼做單元測(cè)試,以及單元測(cè)試中涉及外調(diào)服務(wù)時(shí),如何通過Mock完成測(cè)試。

二、Springboot Service層代碼單元測(cè)試

現(xiàn)在項(xiàng)目都流行前后端代碼分離,后端使用springboot框架,在service層編寫接口代碼實(shí)現(xiàn)邏輯。假設(shè)現(xiàn)在前端不是你寫的,你要對(duì)你自己寫的后端springboot service層提供的接口方法做單元測(cè)試,以確保你寫的代碼是能正常工作的。

Service層代碼單元測(cè)試:一個(gè)簡(jiǎn)單的service調(diào)mapper查詢數(shù)據(jù)庫replay_bug表數(shù)據(jù)量的接口功能

ReplayBugServiceImpl類代碼:

@Service
public class ReplayBugServiceImpl implements ReplayBugService {

    @Autowired
    ReplayBugMapper replayBugMapper;

    @Override
    public int queryBugTotalCount() {
        return replayBugMapper.queryBugTotalCount();
    }
}

replayBugMapper.queryBugTotalCount代碼:

@Select("select count(1) from replay_bug")
int queryBugTotalCount();

單元測(cè)試ReplayBugServiceImplTest類代碼:

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;


@RunWith(SpringRunner.class)
@SpringBootTest
public class ReplayBugServiceImplTest{
    @Autowired
    ReplayBugServiceImpl replayBugService;

    @Test
    public void queryBugTotalCount() {
        int bugCount=replayBugService.queryBugTotalCount();
        System.out.println("結(jié)果是:"+bugCount);
    }
}

代碼很簡(jiǎn)單,調(diào)用這個(gè)接口服務(wù),打印輸出,測(cè)試是否能正確查出數(shù)據(jù)。其中關(guān)鍵的兩個(gè)注解解釋:

@RunWith(SpringRunner.class)注解:是一個(gè)測(cè)試啟動(dòng)器,可以加載SpringBoot測(cè)試注解。
讓測(cè)試在Spring容器環(huán)境下執(zhí)行。如測(cè)試類中無此注解,將導(dǎo)致service、dao等自動(dòng)注入失敗。

@SpringBootTest注解:目的是加載ApplicationContext,啟動(dòng)spring容器。

測(cè)試結(jié)果如下:

Service層代碼單元測(cè)試以及單元測(cè)試如何Mock

更進(jìn)一步,測(cè)試帶入?yún)⒌膕ervice接口:新增接口單元測(cè)試

import com.test.service.BestTest;
import com.test.domain.UrlWhiteListVO;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ReplayUrlWhiteListServiceImplTest{
    @Autowired
    ReplayUrlWhiteListServiceImpl replayUrlWhiteListService;

    private UrlWhiteListVO urlWhiteListVO;

    @Before
    public void setup(){
        urlWhiteListVO=new UrlWhiteListVO();
        urlWhiteListVO.setAppId(78);
        urlWhiteListVO.setAppName("testAPP");
        urlWhiteListVO.setUrlWhite("http://www.baidu.com");
        urlWhiteListVO.setRemarks("測(cè)試一下");
    }

    @Test
    public void save() {
        System.out.println("測(cè)試結(jié)果:"+replayUrlWhiteListService.save(urlWhiteListVO));
    }
}

比之前多了一個(gè)@Before注解,下面自行設(shè)置不同的參數(shù)值,測(cè)試是否在各種入?yún)⑶闆r下接口代碼都沒有問題。

單元測(cè)試結(jié)果:

Service層代碼單元測(cè)試以及單元測(cè)試如何Mock

數(shù)據(jù)庫檢查數(shù)據(jù)插入成功:

Service層代碼單元測(cè)試以及單元測(cè)試如何Mock

三、單元測(cè)試使用Mockito完成Mock測(cè)試

實(shí)際業(yè)務(wù)代碼中可能會(huì)調(diào)到其他第三方接口、會(huì)和數(shù)據(jù)庫有交互,如果要測(cè)試跑通一個(gè)場(chǎng)景,準(zhǔn)備數(shù)據(jù)會(huì)非常麻煩。而單元測(cè)試很多時(shí)候,我們只關(guān)心自己的代碼邏輯是否有漏洞,這個(gè)使用就需要用到Mock, 不真實(shí)調(diào)用,而是將外調(diào)的接口、數(shù)據(jù)庫層面都Mock返回自己想要的各類假數(shù)據(jù)。

因此再進(jìn)一步,單元測(cè)試使用Mockito完成Mock測(cè)試:

import com.test.dao.ReplayBugMapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;


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

    /**
     * 使用@Autowired是讓實(shí)例對(duì)象正常注入
     * 使用@InjectMocks是為了向里面添加@Mock注入的對(duì)象
     * */
    @Autowired
    @InjectMocks
    ReplayBugServiceImpl replayBugService;

    @Mock
    ReplayBugMapper replayBugMapper;
    
    @Before
    public void setup() {
        //添加Mock注解初始化
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void queryBugTotalCount() {
        int count=1;
        Mockito.when(replayBugMapper.queryBugTotalCount()).thenReturn(count);

        int bugCount=replayBugService.queryBugTotalCount();
        System.out.println("Mock單元測(cè)試返回的結(jié)果是:"+bugCount);
    }
}

同樣的接口,之前真實(shí)調(diào)用數(shù)據(jù)庫的時(shí)候,我們看到返回的結(jié)果是3。本次Mock測(cè)試代碼中我們定義了count為1,使用Mockito讓數(shù)據(jù)庫調(diào)用直接Mock返回我們定義的1,不再真實(shí)調(diào)用數(shù)據(jù)庫。

測(cè)試結(jié)果:

Service層代碼單元測(cè)試以及單元測(cè)試如何Mock

Mockito介紹:Mockito是一款用于java開發(fā)的mock測(cè)試框架,用于快速創(chuàng)建和配置mock對(duì)象。通過創(chuàng)建外部依賴的 Mock 對(duì)象, 然后將此 Mock 對(duì)象注入到測(cè)試類中,簡(jiǎn)化有外部依賴的類的測(cè)試。

Mockito使用:在項(xiàng)目pom.xml中引入依賴spring-boot-starter-test,內(nèi)部就依賴了Mockito

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

測(cè)試代碼中用到Mockito的注解作用解釋:

@InjectMocks:讓@Mock(或@Spy)注解創(chuàng)建的mock將被注入到用該實(shí)例中。
@Mock:對(duì)函數(shù)的調(diào)用均執(zhí)行mock,不執(zhí)行真實(shí)調(diào)用。

如果只想對(duì)某一些外調(diào)做mock,其他的外調(diào)都走真實(shí)調(diào)用:

比如Service ReplayServiceImpl中方法如下

public int addBug(ReplayVO replayVO) {
    if(replayManageMapper.addBug(replayVO.getId())==1){
        //判斷如果replay_bug表中已經(jīng)有這條數(shù)據(jù),不再重復(fù)添加。應(yīng)對(duì)場(chǎng)景是用戶多次點(diǎn)擊標(biāo)記記錄為待解決bug。
        if(replayBugService.existBugRecords(replayVO)>=1){
            log.info("replay_bug表中數(shù)據(jù)已存在,不再重復(fù)插入數(shù)據(jù)");
            return 1;
        }else{
            log.info("向replay_bug表中插入數(shù)據(jù)");
            return replayManageMapper.saveToReplayBug(replayVO.getAppId(),replayVO.getRequestId(),replayVO.getId(),replayVO.getAppName(),replayVO.getSysDomain(),replayVO.getSysUrl(),replayVO.getUserAccount(),replayVO.getParameters(),replayVO.getResponse(),replayVO.getReplayStatus(),CommonUtils.convertDateToTime(replayVO.getReplayTime()));
        }
    }else{
        return 0;
    }
}

第一步先調(diào)用replayManageMapper.addBug對(duì)replay表中的這條數(shù)據(jù)更新狀態(tài),更新成功后返回1。
第二步再調(diào)用replayBugService.existBugRecords判斷replay_bug表中是否存在該條記錄,如果存在就不再重復(fù)插入。
第三步如果不存在,就再調(diào)用replayManageMapper.saveToReplayBug,向replay_bug表中插入該條記錄。
現(xiàn)在的需求是單元測(cè)試時(shí),對(duì)第二步外調(diào)的其他接口服務(wù)replayBugService做Mock處理,對(duì)數(shù)據(jù)庫相關(guān)的操作不做Mock,真實(shí)調(diào)用。

單元測(cè)試代碼如下:

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

    private ReplayVO replayVO;
    
    @Autowired
    @InjectMocks
    ReplayServiceImpl replayService;

    @Mock
    ReplayBugService replayBugService;

    @Before
    public void setUp() {

        //添加Mock注解初始化
        MockitoAnnotations.initMocks(this);

        replayVO=new ReplayVO();
        replayVO.setAppId(1);
        replayVO.setRequestId(2);
        replayVO.setId(111);
        replayVO.setAppName("testApp");
        replayVO.setSysDomain("www.test.com");
        replayVO.setSysUrl("http://www.test.com/queryList");
        replayVO.setUserAccount("測(cè)試人員");
        replayVO.setParameters("{\"userID\":\"123\"}");
        replayVO.setResponse("{\"result\":\"成功\"}");
        replayVO.setReplayStatus(5);
        Date date =new Date();
        replayVO.setReplayTime(date);
    }

    @Test
    public void addBug() {
        Mockito.when(replayBugService.existBugRecords(replayVO)).thenReturn(5);
        System.out.println("返回值:"+replayService.addBug(replayVO));
    }
}

代碼解釋:

ReplayBugService做Mock處理,所以加了注解@Mock;
ReplayServiceImpl中,由于需要部分外調(diào)服務(wù)Mock,部分外調(diào)服務(wù)不Mock,所以需要加上注解@Autowired和@InjectMocks:
使用@Autowired是讓實(shí)例對(duì)象正常注入;
使用@InjectMocks是為了向里面添加@Mock注入的對(duì)象;

當(dāng)replayBugService.existBugRecords(replayVO), Mock返回5,測(cè)試結(jié)果為:

Service層代碼單元測(cè)試以及單元測(cè)試如何Mock

當(dāng)replayBugService.existBugRecords(replayVO), Mock返回0,測(cè)試結(jié)果為:

Service層代碼單元測(cè)試以及單元測(cè)試如何Mock

數(shù)據(jù)庫查看,數(shù)據(jù)成功插入:

Service層代碼單元測(cè)試以及單元測(cè)試如何Mock

順帶說一下Mockito的@Spy與@Mock區(qū)別:

@Spy修飾的外部類,必須是真實(shí)存在的,如果沒有我們要自己生成創(chuàng)建

Mockito.doReturn(response).when(testService).save(Mockito.any());

@Mock修飾的外部類,是完全模擬出來的,就算項(xiàng)目中沒有這個(gè)類的實(shí)例,也能自己mock出來一個(gè)。

比如Spring項(xiàng)目中如果你引入了一個(gè)外部的Service:

  • 如果在寫單元測(cè)試時(shí)候,外部的Service能加載到的話就可以使用@Spy注解,因?yàn)镾pring能為你從外部服務(wù)找到這個(gè)Service并生成實(shí)例注入。
  • 但是如果外部的服務(wù)沒有部署,那么Spring就不能為你創(chuàng)建實(shí)例,就會(huì)報(bào)錯(cuò)提示你在創(chuàng)建@Spy修飾服務(wù)必須要先實(shí)例,此時(shí)只要用@Mock注解替換@Spy就好了。

最后,如果有很多的類都需要做單元測(cè)試,每一個(gè)單元測(cè)試類的頭上都加公共的注解:
@RunWith(SpringRunner.class)
@SpringBootTest
就顯得比較麻煩,可以抽出來寫成一個(gè)Base類,如果Springboot項(xiàng)目有一些公共的配置需要添加也可以放在這個(gè)Base類中:

import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

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

    @BeforeClass
    public static void init(){
        System.setProperty("server.domain", "test.server.com");
    }
}

然后其他單元測(cè)試類使用時(shí)繼承這個(gè)BaseTest類就OK了,不用再每個(gè)類都去加公共的注解、配置:

public class ReplayServiceImplTest extends BestTest

================================================================================================
以上就是本次的全部?jī)?nèi)容,都看到這里了,如果對(duì)你有幫助,麻煩點(diǎn)個(gè)贊+收藏+關(guān)注,一鍵三連啦~

歡迎下方掃碼關(guān)注我的vx公眾號(hào):程序員楊叔,各類文章都會(huì)第一時(shí)間在上面發(fā)布,持續(xù)分享全棧測(cè)試知識(shí)干貨,你的支持就是作者更新最大的動(dòng)力~文章來源地址http://www.zghlxwxcb.cn/news/detail-404513.html

到了這里,關(guān)于Service層代碼單元測(cè)試以及單元測(cè)試如何Mock的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Spring Boot 單元測(cè)試(Controller測(cè)試與Service測(cè)試)

    Spring Boot 單元測(cè)試(Controller測(cè)試與Service測(cè)試)

    ??博客主頁:??我的主頁?? ??歡迎點(diǎn)贊 ?? 收藏 ??留言 ?? 歡迎討論!?? ??本文由 【泠青沼~】 原創(chuàng),首發(fā)于 CSDN?????? ??由于博主是在學(xué)小白一枚,難免會(huì)有錯(cuò)誤,有任何問題歡迎評(píng)論區(qū)留言指出,感激不盡!??個(gè)人主頁 @SpringBootTest相當(dāng)于springMvc中單元測(cè)試中的

    2023年04月26日
    瀏覽(26)
  • springboot對(duì)service方法進(jìn)行單元測(cè)試

    1. 在pom.xml文件添加依賴 2. service類 這里為了簡(jiǎn)化,沒有將接口和實(shí)現(xiàn)單獨(dú)定義。 3. 測(cè)試類 @SpringBootTest注解會(huì)將springboot程序完整的運(yùn)行起來。還可以寫成@SpringBootTest(classes =?OrderApplication.class),即指定啟動(dòng)類。? 4. 執(zhí)行測(cè)試 5. 除了啟動(dòng)整個(gè)應(yīng)用以外,還可以只加載需要的組件

    2024年02月11日
    瀏覽(23)
  • springboot項(xiàng)目使用Junit5 + mockito + jacoco 實(shí)現(xiàn)單元測(cè)試以及代碼覆蓋率檢查

    在創(chuàng)建springboot項(xiàng)目時(shí)會(huì)默認(rèn)添加spring-boot-starter-test依賴,其中已經(jīng)包含了junit、mockito依賴,根據(jù)springboot版本的不同junit和mockito的版本也會(huì)有所不同 先說一下各自功能: junit只說一點(diǎn),junt4和junit5的注解不同,使用方式略有差異,其他不贅述了,基本用法都懂。 mockito是mock的

    2023年04月23日
    瀏覽(33)
  • 如何有效保證Java代碼單元測(cè)試覆蓋率

    如何有效保證Java代碼單元測(cè)試覆蓋率

    我們?cè)趯?shí)際項(xiàng)目開發(fā)過程中,不同level的童鞋由于專業(yè)技能的層次不同,導(dǎo)致在參與實(shí)際開發(fā)的業(yè)務(wù)代碼中經(jīng)常會(huì)出現(xiàn)各種bug,項(xiàng)目管理中好的pm或許會(huì)給充足的時(shí)間來讓開發(fā)童鞋們定位修復(fù)這些bug,也有各種客觀原因的PM不會(huì)在項(xiàng)目中預(yù)留這些時(shí)間,往往就需要開發(fā)自己通過

    2023年04月17日
    瀏覽(21)
  • 36-代碼測(cè)試(上):如何編寫Go語言單元測(cè)試和性能測(cè)試用例?

    36-代碼測(cè)試(上):如何編寫Go語言單元測(cè)試和性能測(cè)試用例?

    每種語言通常都有自己的測(cè)試包/模塊,Go語言也不例外。在Go中,我們可以通過 testing 包對(duì)代碼進(jìn)行單元測(cè)試和性能測(cè)試。? Go語言有自帶的測(cè)試框架 testing ,可以用來實(shí)現(xiàn)單元測(cè)試(T類型)和性能測(cè)試(B類型),通過 go test 命令來執(zhí)行單元測(cè)試和性能測(cè)試。 go test 執(zhí)行測(cè)試

    2024年04月11日
    瀏覽(25)
  • Spring Boot集成單元測(cè)試調(diào)用dao,service

    Spring Boot集成單元測(cè)試調(diào)用dao,service

    溫馨提示:本人開發(fā)上線視頻網(wǎng)站,有想要的看視頻的,可以看看。小松鼠

    2024年02月14日
    瀏覽(22)
  • Mock單元測(cè)試----對(duì)Controller層進(jìn)行單獨(dú)測(cè)試,不調(diào)用Service層

    前言:根據(jù)相關(guān)需求,需要對(duì)編寫的代碼進(jìn)行邏輯檢測(cè)以及功能的完整性,從而開始了單元測(cè)試之路。在編寫的中間段時(shí),突然被 不經(jīng)過Service層直接測(cè)試Controller層 這個(gè)要求難住了。在我看來,單元測(cè)試除了Junit還是Junit,屬實(shí)是學(xué)藝不精,之后接觸了Mock,才發(fā)現(xiàn)Mock太牛逼了

    2024年02月05日
    瀏覽(18)
  • 如何使用PHPUnit編寫一個(gè)PHP單元測(cè)試-簡(jiǎn)單的代碼示例

    在軟件開發(fā)過程中,單元測(cè)試是一種重要的測(cè)試方法,可以確保代碼的質(zhì)量和可靠性。在PHP開發(fā)中,也可以通過編寫單元測(cè)試來驗(yàn)證代碼的正確性。下面將介紹一些編寫PHP單元測(cè)試的基本步驟和常用工具。 首先,你需要一個(gè)PHP單元測(cè)試框架,比如PHPUnit。PHPUnit是PHP社區(qū)最流行

    2024年02月04日
    瀏覽(39)
  • SpringBoot——Service單元測(cè)試(包含mybatis、mapper、私有方法等)

    ??在寫單元測(cè)試時(shí),免不了遇到私有方法、數(shù)據(jù)庫等一些操作,此時(shí)就需要一些mock處理。

    2024年02月13日
    瀏覽(25)
  • 如何讓chatgpt十分正確的幫咱們編寫代碼文檔和單元測(cè)試

    ? 有多少次你專注于編程而忘記了寫函數(shù)、方法、類的非常簡(jiǎn)單的代碼文檔?我不是在問單元測(cè)試.?直到我發(fā)現(xiàn)ChatGPT可以做到這一點(diǎn): 除了代碼文檔,它在編寫單元測(cè)試方面也做得很好。此外,在最后,我可以要求他為其他想使用我的代碼的貢獻(xiàn)者生成一個(gè)用戶友好的文檔。

    2024年02月15日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包