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

使用Mock進(jìn)行業(yè)務(wù)邏輯層Service測(cè)試詳解

 更新時(shí)間:2023年08月29日 11:35:52   作者:瘋狂的帆  
這篇文章主要介紹了使用Mock進(jìn)行業(yè)務(wù)邏輯層Service測(cè)試詳解,mock是一種模擬對(duì)象的技術(shù),用于在測(cè)試過(guò)程中替代真實(shí)的對(duì)象,通過(guò)mock,我們可以控制被模擬對(duì)象的行為和返回值,以便進(jìn)行更加精確的測(cè)試,需要的朋友可以參考下

場(chǎng)景

公司采用的是分層開(kāi)發(fā),controller、Service、dao層分離,現(xiàn)在寫dao層代碼的人生病了,進(jìn)度比較慢,現(xiàn)在你寫的是 Service層的代碼,怎么測(cè)試 Service 層代碼是否正確呢?

Service層測(cè)試的重點(diǎn)是什么?

  • DAO層調(diào)用的次數(shù)
  • 以及調(diào)用的順序
  • 并不關(guān)心最后數(shù)據(jù)是否準(zhǔn)確

mock是什么?

在軟件測(cè)試中,mock是一種模擬對(duì)象的技術(shù),用于在測(cè)試過(guò)程中替代真實(shí)的對(duì)象。

通過(guò)mock,我們可以控制被模擬對(duì)象的行為和返回值,以便進(jìn)行更加精確的測(cè)試。

測(cè)試代碼示例

準(zhǔn)備環(huán)境

引入依賴

<!-- Junit測(cè)試包 -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
</dependency>
<!-- 專門用來(lái)做業(yè)務(wù)邏輯層 或者 Controller層的測(cè)試的 -->
<dependency>
    <groupId>org.easymock</groupId>
    <artifactId>easymock</artifactId>
    <version>3.5.1</version>
</dependency>

準(zhǔn)備Dao層測(cè)試接口,不需要方法的實(shí)現(xiàn)

public interface AaDao {
    void a();
    void b();
}
public interface BbDao {
    void c();
    void d();
}

service 測(cè)試代碼

public interface ABService {
    void aa();
    void bb();
    void cc();
    void dd();
}

testService 在此方法中使用 mock 進(jìn)行測(cè)試

public class TestService {
    private ABService abService = new ABServiceImpl();
}

1. 簡(jiǎn)單測(cè)試 createMock

@Override
public void aa() {
    aDao.a();
}

測(cè)試代碼

@Test
public void testAA() {
    // 創(chuàng)建對(duì)象
    AaDao aaDao = EasyMock.createStrictMock(AaDao.class);
    // 記錄
    aaDao.a();
    EasyMock.expectLastCall();
    // 使能設(shè)置
    EasyMock.replay(aaDao);
    // 接下來(lái)調(diào)用Service進(jìn)行測(cè)試
    abService.setaDao(aaDao);
    abService.aa();
    // 進(jìn)行校驗(yàn)
    EasyMock.verify(aaDao);
}

2. 測(cè)試調(diào)用順序 createStrictMock

@Override
public void ee() {
    aDao.b();
    aDao.a();
}

測(cè)試代碼1

// 測(cè)試調(diào)用順序
@Test
public void testEE1() {
    // 創(chuàng)建對(duì)象
    AaDao aaDao = EasyMock.createMock(AaDao.class);
    // 進(jìn)行記錄
    aaDao.a();
    EasyMock.expectLastCall();
    aaDao.b();
    EasyMock.expectLastCall();
    // 使能設(shè)置,保存記錄信息
    EasyMock.replay(aaDao);
    // 調(diào)用 Service 測(cè)試
    abService.setaDao(aaDao);
    abService.ee();
    // 進(jìn)行校驗(yàn)
    EasyMock.verify(aaDao);
}

運(yùn)行此代碼,結(jié)果竟然是正確的,明明調(diào)用順序不一致,卻還是正確,這顯然是不對(duì)的

測(cè)試代碼2 使用createStrictMock

@Test
public void testEE2() {
    // 創(chuàng)建對(duì)象
    AaDao aaDao = EasyMock.createStrictMock(AaDao.class);
    // 進(jìn)行記錄
    aaDao.b();
    EasyMock.expectLastCall();
    aaDao.a();
    EasyMock.expectLastCall();
    // 使能設(shè)置,保存記錄信息
    EasyMock.replay(aaDao);
    // 調(diào)用 Service 測(cè)試
    abService.setaDao(aaDao);
    abService.ee();
    // 進(jìn)行校驗(yàn)
    EasyMock.verify(aaDao);
}

3. 測(cè)試方法多次調(diào)用以及調(diào)用順序

@Override
public void bb() {
    aDao.a();
    aDao.b();
    aDao.b();
    aDao.a();
}

測(cè)試代碼

@Test
public void testBB() {
    // 創(chuàng)建對(duì)象
    AaDao aaDao = EasyMock.createStrictMock(AaDao.class);
    // 記錄
    aaDao.a();
    EasyMock.expectLastCall();
    aaDao.b();
    EasyMock.expectLastCall();
    aaDao.b();
    EasyMock.expectLastCall();
    aaDao.a();
    EasyMock.expectLastCall();
    // 使能設(shè)置,即保存記錄信息
    EasyMock.replay(aaDao);
    // 調(diào)用 Service 測(cè)試
    abService.setaDao(aaDao);
    abService.bb();
    // 進(jìn)行校驗(yàn)
    EasyMock.verify(aaDao);
}

如果是多次調(diào)用的話,就需要書寫多次記錄

4. 測(cè)試調(diào)用不同dao的方法

@Override
public void cc() {
    aDao.a();
    bDao.c();
}

測(cè)試代碼1

@Test
public void testCC1() {
    // 創(chuàng)建對(duì)象
    AaDao aaDao = EasyMock.createStrictMock(AaDao.class);
    BbDao bbDao = EasyMock.createStrictMock(BbDao.class);
    // 進(jìn)行記錄
    bbDao.c();
    EasyMock.expectLastCall();
    aaDao.a();
    EasyMock.expectLastCall();
    // 使能設(shè)置,保存記錄信息
    EasyMock.replay(aaDao, bbDao);
    // 調(diào)用 Service 測(cè)試
    abService.setaDao(aaDao);
    abService.setbDao(bbDao);
    abService.cc();
    // 進(jìn)行校驗(yàn)
    EasyMock.verify(aaDao, bbDao);
}

可以看出來(lái),createStrictMock方法并不能保證多個(gè) dao之間的調(diào)用順序,只能對(duì)單個(gè)的DAO的調(diào)用順序有嚴(yán)格的要求

測(cè)試代碼2 createStrictControl

@Test
public void testCC2() {
    // 創(chuàng)建一個(gè) controller,約束這些dao是一個(gè)整體
    IMocksControl control = EasyMock.createStrictControl();
    // 創(chuàng)建對(duì)象
    AaDao aaDao = control.createMock(AaDao.class);
    BbDao bbDao = control.createMock(BbDao.class);
    // 進(jìn)行記錄
    aaDao.a();
    EasyMock.expectLastCall();
    bbDao.c();
    EasyMock.expectLastCall();
    // 使能設(shè)置,保存記錄信息
    control.replay();
    // 調(diào)用 Service 測(cè)試
    abService.setaDao(aaDao);
    abService.setbDao(bbDao);
    abService.cc();
    // 進(jìn)行校驗(yàn)
    control.verify();
}

使用 createStrictControl 定義一個(gè)整體,進(jìn)行多個(gè) dao 的測(cè)試

5. 測(cè)試不同dao調(diào)用順序及次數(shù)

@Override
public void dd() {
    aDao.a();
    bDao.c();
    bDao.d();
    aDao.a();
}

測(cè)試代碼

@Test
public void testDD() {
    // 創(chuàng)建一個(gè) controller,約束這些dao是一個(gè)整體
    IMocksControl control = EasyMock.createStrictControl();
    // 創(chuàng)建對(duì)象
    AaDao aaDao = control.createMock(AaDao.class);
    BbDao bbDao = control.createMock(BbDao.class);
    // 進(jìn)行記錄
    aaDao.a();
    EasyMock.expectLastCall();
    bbDao.c();
    EasyMock.expectLastCall();
    bbDao.d();
    EasyMock.expectLastCall();
    aaDao.a();
    EasyMock.expectLastCall();
    // 使能設(shè)置,保存記錄信息
    control.replay();
    // 調(diào)用 Service 測(cè)試
    abService.setaDao(aaDao);
    abService.setbDao(bbDao);
    abService.dd();
    // 進(jìn)行校驗(yàn)
    control.verify();
}

測(cè)試此方法時(shí),即便是調(diào)換 同一個(gè)dao的方法也會(huì)報(bào)錯(cuò),滿足條件

總結(jié)

測(cè)試 service 層時(shí),可以使用 mock 框架進(jìn)行測(cè)試,引入 mock依賴即可,操作簡(jiǎn)單

如果測(cè)試的 service 只包含一個(gè)dao,那么使用 EasyMock.createStrictMock() 即可進(jìn)行測(cè)試

如果測(cè)試的 service 包含多個(gè)dao,那么使用 EasyMock.createStrictControl(); 創(chuàng)建一個(gè) control 進(jìn)行包裹即可測(cè)試

到此這篇關(guān)于使用Mock進(jìn)行業(yè)務(wù)邏輯層Service測(cè)試詳解的文章就介紹到這了,更多相關(guān)Mock測(cè)試Service內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Java中的封裝、繼承、多態(tài)

    詳解Java中的封裝、繼承、多態(tài)

    本文主要介紹了Java中的封裝、繼承、多態(tài)的相關(guān)知識(shí),具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-01-01
  • Java-lambda表達(dá)式入門看這一篇就夠了

    Java-lambda表達(dá)式入門看這一篇就夠了

    lambda表達(dá)式最簡(jiǎn)單的作用就是用于簡(jiǎn)化創(chuàng)建匿名內(nèi)部類對(duì)象,Lambda表達(dá)式是一個(gè)可傳遞的代碼塊,可以在以后執(zhí)行一次或多次,下面通過(guò)本文給大家介紹Java-lambda表達(dá)式入門教程,感興趣的朋友一起看看吧
    2021-05-05
  • lombok注解@Data使用在繼承類上時(shí)出現(xiàn)警告的問(wèn)題及解決

    lombok注解@Data使用在繼承類上時(shí)出現(xiàn)警告的問(wèn)題及解決

    Lombok的@Data注解簡(jiǎn)化了實(shí)體類代碼,但在子類中使用時(shí)會(huì)出現(xiàn)警告,指出equals和hashCode方法不會(huì)考慮父類屬性,解決方法有兩種:一是在父類上使用@EqualsAndHashCode(callSuper=true)注解;二是通過(guò)配置lombok.config文件,均能有效解決警告問(wèn)題
    2024-10-10
  • Java實(shí)現(xiàn)批量向mysql寫入數(shù)據(jù)的方法

    Java實(shí)現(xiàn)批量向mysql寫入數(shù)據(jù)的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)批量向mysql寫入數(shù)據(jù)的方法,涉及java基于JDBC連接mysql數(shù)據(jù)庫(kù)及寫入數(shù)據(jù)的相關(guān)操作技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下
    2017-12-12
  • Spring security基于數(shù)據(jù)庫(kù)中賬戶密碼認(rèn)證

    Spring security基于數(shù)據(jù)庫(kù)中賬戶密碼認(rèn)證

    這篇文章主要介紹了Spring security基于數(shù)據(jù)庫(kù)中賬戶密碼認(rèn)證,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • JAVA熔斷和降級(jí)真實(shí)關(guān)系的圖文詳解

    JAVA熔斷和降級(jí)真實(shí)關(guān)系的圖文詳解

    這篇文章主要介紹了Java熔斷和降級(jí)的關(guān)系,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Spring創(chuàng)建Bean的生命周期詳析

    Spring創(chuàng)建Bean的生命周期詳析

    這篇文章主要介紹了Spring創(chuàng)建Bean的生命周期詳析,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • Spring Boot集成Resilience4J實(shí)現(xiàn)限流/重試/隔離

    Spring Boot集成Resilience4J實(shí)現(xiàn)限流/重試/隔離

    在Java的微服務(wù)生態(tài)中,對(duì)于服務(wù)保護(hù)組件,像springcloud的Hystrix,springcloud?alibaba的Sentinel,以及當(dāng)Hystrix停更之后官方推薦使用的Resilience4j,所以本文給大家介紹了Spring Boot集成Resilience4J實(shí)現(xiàn)限流/重試/隔離,需要的朋友可以參考下
    2024-03-03
  • SpringBoot中注解@ConfigurationProperties與@Value的區(qū)別與使用詳解

    SpringBoot中注解@ConfigurationProperties與@Value的區(qū)別與使用詳解

    本文主要介紹了SpringBoot中注解@ConfigurationProperties與@Value的區(qū)別與使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的長(zhǎng)輪詢的示例代碼

    Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的長(zhǎng)輪詢的示例代碼

    長(zhǎng)輪詢是與服務(wù)器保持即時(shí)通信的最簡(jiǎn)單的方式,它不使用任何特定的協(xié)議,例如 WebSocket ,所以也不依賴于瀏覽器版本等外部條件的兼容性。本文將用Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的長(zhǎng)輪詢,需要的可以參考一下
    2022-08-08

最新評(píng)論

吉安市| 西贡区| 阳信县| 思南县| 镇江市| 南漳县| 泰兴市| 大埔县| 九江县| 新竹市| 正安县| 叶城县| 新野县| 枞阳县| 台山市| 大关县| 阿合奇县| 平远县| 延长县| 宜春市| 新宁县| 镇原县| 蒙城县| 漳平市| 都昌县| 芦山县| 荥经县| 岳阳县| 钟祥市| 上犹县| 丰县| 乐安县| 锦屏县| 兰州市| 临江市| 嘉荫县| 赤峰市| 长治市| 淳安县| 敦化市| 玉屏|