女人荫蒂被添全过程13种图片,亚洲+欧美+在线,欧洲精品无码一区二区三区 ,在厨房拨开内裤进入毛片

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

一種極簡單的SpringBoot單元測試方法

京東云 ? 來源:jf_75140285 ? 作者:jf_75140285 ? 2025-03-11 15:39 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

前言

本文主要提供了一種單元測試方法,力求0基礎人員可以從本文中受到啟發,可以搭建一套好用的單元測試環境,并能切實的提高交付代碼的質量。極簡體現在除了POM依賴和單元測試類之外,其他什么都不需要引入,只需要一個本地能啟動的springboot項目。

目錄

1.POM依賴

2.單元測試類示例及注解釋義

3.單元測試經驗總結

一、POM依賴

Springboot版本: 2.6.6


  org.springframework.boot
  spring-boot-starter-test
  test


  org.mockito
  mockito-core
  3.12.4



二、單元測試類示例

主要有兩種

第一種,偏集成測試

需要啟動項目,需要連接數據庫、RPC注冊中心

主要注解:@SpringBootTest + @RunWith(SpringRunner.class) + @Transactional + @Resource + @SpyBean + @Test

?@SpringBootTest + @RunWith(SpringRunner.class) 啟動了一套springboot的測試環境;

?@Transactional 對于一些修改數據庫的操作,會執行回滾,能測試執行sql,但是又不會真正的修改測試庫的數據;

?@Resource 主要引入被測試的類

?@SpyBean springboot環境下mock依賴的bean,可以搭配Mockito.doAnswer(…).when(xxServiceImpl).xxMethod(any())mock特定方法的返回值;

?@Test 標識一個測試方法

TIP:對于打樁有這幾個注解@Mock @Spy @MockBean @SpyBean,每一個都有其對應的搭配,簡單說@Mock和@Spy要搭配@InjectMocks去使用,@MockBean和@SpyBean搭配@SpringBootTest + @RunWith(SpringRunner.class)使用,@InjectMocks不用啟動應用,它啟動了一個完全隔離的測試環境,無法使用spring提供的所有bean,所有的依賴都需要被mock

上代碼:

/**
 * @author jiangbo8
 * @since 2024/4/24 9:52
 */
@Transactional
@SpringBootTest
@RunWith(SpringRunner.class)
public class SalesAmountPlanControllerAppTest {
    @Resource
    private SalesAmountPlanController salesAmountPlanController;
    @SpyBean
    private ISaleAmountHourHistoryService saleAmountHourHistoryServiceImpl;
    @SpyBean
    private ISaleAmountHourForecastService saleAmountHourForecastServiceImpl;
    @SpyBean
    private ISaleAmountHourPlanService saleAmountHourPlanServiceImpl;

    @Test
    public void testGraph1()  {
        // 不寫mock就走實際調用

        SalesAmountDTO dto = new SalesAmountDTO();
        dto.setDeptId1List(Lists.newArrayList(35));
        dto.setDeptId2List(Lists.newArrayList(235));
        dto.setDeptId3List(Lists.newArrayList(100));
        dto.setYoyType(YoyTypeEnum.SOLAR.getCode());
        dto.setShowWeek(true);
        dto.setStartYm("2024-01");
        dto.setEndYm("2024-10");
        dto.setTimeDim(GraphTimeDimensionEnum.MONTH.getCode());
        dto.setDataType(SalesAmountDataTypeEnum.AMOUNT.getCode());
        Result result = salesAmountPlanController.graph(dto);
        System.out.println(JSON.toJSONString(result));
        Assert.assertNotNull(result);
    }

    @Test
    public void testGraph11()  {
        // mock就走mock
        Mockito.doAnswer(this::mockSaleAmountHourHistoryListQuery).when(saleAmountHourHistoryServiceImpl).listBySaleAmountQueryBo(any());
        Mockito.doAnswer(this::mockSaleAmountHourPlansListQuery).when(saleAmountHourPlanServiceImpl).listBySaleAmountQueryBo(any());
        Mockito.doAnswer(this::mockSaleAmountHourForecastListQuery).when(saleAmountHourForecastServiceImpl).listBySaleAmountQueryBo(any());

        SalesAmountDTO dto = new SalesAmountDTO();
        dto.setDeptId1List(Lists.newArrayList(111));
        dto.setDeptId2List(Lists.newArrayList(222));
        dto.setDeptId3List(Lists.newArrayList(333));
        dto.setYoyType(YoyTypeEnum.SOLAR.getCode());
        dto.setShowWeek(true);
        dto.setStartYm("2024-01");
        dto.setEndYm("2024-10");
        dto.setTimeDim(GraphTimeDimensionEnum.MONTH.getCode());
        dto.setDataType(SalesAmountDataTypeEnum.AMOUNT.getCode());
        Result result = salesAmountPlanController.graph(dto);
        System.out.println(JSON.toJSONString(result));
        Assert.assertNotNull(result);
    }
    
	private List mockSaleAmountHourHistoryListQuery(org.mockito.invocation.InvocationOnMock s) {
        SaleAmountQueryBo queryBo = s.getArgument(0);
        if (queryBo.getGroupBy().contains("ymd")) {
            List historyList = Lists.newArrayList();
            List ymdList = DateUtil.rangeWithDay(DateUtil.parseFirstDayLocalDate(queryBo.getStartYm()), DateUtil.parseLastDayLocalDate(queryBo.getStartYm()));
            for (String ymd : ymdList) {
                SaleAmountHourHistory history = new SaleAmountHourHistory();
                history.setYear(Integer.parseInt(queryBo.getStartYm().split("-")[0]));
                history.setMonth(Integer.parseInt(queryBo.getStartYm().split("-")[1]));
                history.setYm(queryBo.getStartYm());
                history.setYmd(DateUtil.parseLocalDateByYmd(ymd));

                history.setAmount(new BigDecimal("1000"));
                history.setAmountSp(new BigDecimal("2000"));
                history.setAmountLunarSp(new BigDecimal("3000"));

                history.setSales(new BigDecimal("100"));
                history.setSalesSp(new BigDecimal("200"));
                history.setSalesLunarSp(new BigDecimal("300"));

                history.setCostPrice(new BigDecimal("100"));
                history.setCostPriceSp(new BigDecimal("100"));
                history.setCostPriceLunarSp(new BigDecimal("100"));
                historyList.add(history);
            }

            return historyList;
        }

        List ymList = DateUtil.rangeWithMonth(DateUtil.parseFirstDayLocalDate(queryBo.getStartYm()), DateUtil.parseLastDayLocalDate(queryBo.getEndYm()));
        List historyList = Lists.newArrayList();
        for (String ym : ymList) {
            SaleAmountHourHistory history = new SaleAmountHourHistory();
            history.setYear(Integer.parseInt(ym.split("-")[0]));
            history.setMonth(Integer.parseInt(ym.split("-")[1]));
            history.setYm(ym);

            history.setAmount(new BigDecimal("10000"));
            history.setAmountSp(new BigDecimal("20000"));
            history.setAmountLunarSp(new BigDecimal("30000"));

            history.setSales(new BigDecimal("1000"));
            history.setSalesSp(new BigDecimal("2000"));
            history.setSalesLunarSp(new BigDecimal("3000"));

            history.setCostPrice(new BigDecimal("100"));
            history.setCostPriceSp(new BigDecimal("100"));
            history.setCostPriceLunarSp(new BigDecimal("100"));
            historyList.add(history);
        }

        return historyList;
    } 
}

第二種,單元測試

不需要啟動項目,也不會連接數據庫、RPC注冊中心等,但是相應的所有數據都需要打樁mock

這種方法可以使用testMe快速生成單元測試類的框架,具體方法見: 基于testMe快速生成單元測試類(框架)

主要注解:@InjectMocks + @Mock + @Test

?@InjectMocks標識了一個需要被測試的類,這個類中依賴的bean都需要被@Mock,并mock返回值,不然就會空指針

?@Mock mock依賴,具體mock數據還要搭配when(xxService.xxMethod(any())).thenReturn(new Object()); mock返回值

?@Test 標識一個測試方法

上代碼:

/**
 * Created by jiangbo8 on 2022/10/17 15:02
 */
public class CheckAndFillProcessorTest {
    @Mock
    Logger log;
    @Mock
    OrderRelService orderRelService;
    @Mock
    VenderServiceSdk venderServiceSdk;
    @Mock
    AfsServiceSdk afsServiceSdk;
    @Mock
    PriceServiceSdk priceServiceSdk;
    @Mock
    ProductInfoSdk productInfoSdk;
    @Mock
    OrderMidServiceSdk orderMidServiceSdk;
    @Mock
    OrderQueueService orderQueueService;
    @Mock
    SendpayMarkService sendpayMarkService;
    @Mock
    TradeOrderService tradeOrderService;

    @InjectMocks
    CheckAndFillProcessor checkAndFillProcessor;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testProcess2() throws Exception {

        OrderRel orderRel = new OrderRel();
        //orderRel.setJdOrderId(2222222L);
        orderRel.setSopOrderId(1111111L);
        orderRel.setVenderId("123");

        when(orderRelService.queryOrderBySopOrderId(anyLong())).thenReturn(orderRel);

        OrderDetailRel orderDetailRel = new OrderDetailRel();
        orderDetailRel.setJdSkuId(1L);
        when(orderRelService.queryDetailList(any())).thenReturn(Collections.singletonList(orderDetailRel));

        Vender vender = new Vender();
        vender.setVenderId("123");
        vender.setOrgId(1);
        when(venderServiceSdk.queryVenderByVenderId(anyString())).thenReturn(vender);
        when(afsServiceSdk.queryAfsTypeByJdSkuAndVender(anyLong(), anyString())).thenReturn(0);
        when(priceServiceSdk.getJdToVenderPriceByPriorityAndSaleTime(anyString(), anyString(), any())).thenReturn(new BigDecimal("1"));
        when(productInfoSdk.getProductInfo(any())).thenReturn(new HashMap>() {{
            put(1L, new HashMap() {{
                put("String", "String");
            }});
        }});

        when(orderQueueService.updateQueueBySopOrderId(any())).thenReturn(true);

        Order sopOrder = new Order();
        sopOrder.setYn(1);
        when(orderMidServiceSdk.getOrderByIdFromMiddleWare(anyLong())).thenReturn(sopOrder);

        when(sendpayMarkService.isFreshOrder(anyLong(), anyString())).thenReturn(true);

        doNothing().when(tradeOrderService).fillOrderProduceTypeInfo(any(), anyInt(), any());
        doNothing().when(tradeOrderService).fillOrderFlowFlagInfo(any(), any(), anyInt(), any());

        Field field = ResourceContainer.class.getDeclaredField("allInPlateConfig");
        field.setAccessible(true);
        field.set("allInPlateConfig", new AllInPlateConfig());

        OrderQueue orderQueue = new OrderQueue();
        orderQueue.setSopOrderId(1111111L);
        DispatchResult result = checkAndFillProcessor.process(orderQueue);
        Assert.assertNotNull(result);
    }
}

三、單元測試經驗總結

在工作中總結了一些單元測試的使用場景:

1.重構,如果我們拿到了一個代碼,我們要去重構這個代碼,如果這個代碼本身的單元測試比較完善,那么我們重構完之后可以執行一下現有的單元測試,以保證重構前后代碼在各個場景的邏輯保證最終一致,但是如果單元測試不完善甚至沒有,那我建議大家可以基于AI去生成這個代碼的單元測試,然后進行重構,再用生成的單元測試去把控質量,這里推薦Diffblue去生成,有興趣的可以去了解一下。

2.新功能,新功能建議使用上面推薦的兩種方法去做單測,第一種方法因為偏集成測試,單元測試代碼編寫的壓力比較小,可以以黑盒測試的視角去覆蓋測試case就可以了,但是如果某場景極為復雜,想要單獨對某個復雜計算代碼塊進行專門的測試,那么可以使用第二種方法,第二種方法是很單純的單元測試,聚焦專門代碼塊,但是如果普遍使用的話,單元測試代碼編寫量會很大,不建議單純使用某一種,可以具體情況具體分析。

建議大家做單元測試不要單純的追求行覆蓋率,還是要本著提高質量的心態去做單元測試。

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 測試
    +關注

    關注

    8

    文章

    5678

    瀏覽量

    128677
  • 單元測試
    +關注

    關注

    0

    文章

    50

    瀏覽量

    3307
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    電源與時鐘的單元測試方案解析

    單元測試的問題全部要提問題單跟蹤解決,測出問題在記錄在跟蹤表的同時就馬上提問題單(單元測試的問題單可以走短流程),不要積累到最后起提。
    發表于 03-03 14:45 ?1377次閱讀

    MCU進行單元測試方法

    背景MCU軟件不同于常規的PC機或基于SOC的嵌入式軟件,其般情況下,與底層硬件耦合度高,資源有限,如何進行單元測試的問題困擾我很久。解決方案根據目前已知如下3類型的方案:在目標板上運行此方案下,在程序代碼中加入
    發表于 11-01 06:58

    單元測試/集成測試自動化工具--WinAMS

    的對安全性要求極高的領域,單元測試已經成為不可缺少的部分。使用目標機代碼進行單元測試也是為了符合汽車行業中ISO26262功能安全認證標準。產品特長全面支持嵌入式微機!驗證嵌入式C/C++軟件 實施以模塊
    發表于 06-17 18:26

    如何提高嵌入式軟件單元測試效率

    每個代碼片段是否按預期工作。 如果運行回歸測試套件太耗時: ·工程資源在等待測試完成時未被使用·代碼質量因代碼測試頻率降低而降低·上市時間增加本指南介紹了一種使用虛擬平臺的
    發表于 08-28 06:31

    系統測試單元測試、集成測試、驗收測試、回歸測試

    系統測試單元測試、集成測試、驗收測試、回歸測試 單元測試
    發表于 10-22 12:38 ?1924次閱讀

    單元測試常用的方法

    單元測試,是指對軟件中的最小可測試單元進行檢查和驗證。對于單元測試單元的含義,般來說,要根據
    發表于 12-21 10:17 ?3.7w次閱讀
    <b class='flag-5'>單元測試</b>常用的<b class='flag-5'>方法</b>

    什么是單元測試_單元測試的目的是什么

    工廠在組裝臺電視機之前,會對每個元件都進行測試,這,就是單元測試。單元測試是開發者編寫的小段代碼,用于檢驗被測代碼的
    發表于 12-21 13:44 ?3.3w次閱讀

    java單元測試的好處

    單元測試是編寫測試代碼,應該準確、快速地保證程序基本模塊的正確性。好的單元測試的標準,JUnit是Java單元測試框架,已經在Eclipse中默認安裝。許多開發者都有個習慣,常常不樂意
    發表于 12-21 14:24 ?4098次閱讀

    java單元測試怎么寫

    Java是門面向對象編程語言,不僅吸收了C++語言的各種優點,還摒棄了C++里難以理解的多繼承、指針等概念,因此Java語言具有功能強大和簡單易用兩個特征。單元測試,是指對軟件中的最小可測試
    發表于 12-21 14:54 ?8600次閱讀
    java<b class='flag-5'>單元測試</b>怎么寫

    什么是單元測試,為什么要做單元測試

    。 什么是單元測試? 單元測試(unit testing),是指對軟件中的最小可測試單元進行檢查和驗證。通常而言,
    的頭像 發表于 04-28 17:21 ?1w次閱讀

    MCU如何進行單元測試

    背景MCU軟件不同于常規的PC機或基于SOC的嵌入式軟件,其般情況下,與底層硬件耦合度高,資源有限,如何進行單元測試的問題困擾我很久。解決方案根據目前已知如下3類型的方案:在目標板上運行此方案下,在程序代碼中加入
    發表于 10-26 10:06 ?35次下載
    MCU如何進行<b class='flag-5'>單元測試</b>

    RT-Thread上的單元測試:什么是單元測試單元測試的作用是什么?

    RT-Thread上的單元測試:什么是單元測試?單元測試的作用是什么? ? ? ? ? ? 審核編輯:彭靜
    的頭像 發表于 05-27 16:06 ?1987次閱讀
    RT-Thread上的<b class='flag-5'>單元測試</b>:什么是<b class='flag-5'>單元測試</b>?<b class='flag-5'>單元測試</b>的作用是什么?

    軟件單元測試真的有必要嗎?(上)

    本文著重探討單元測試的重要性及其正面臨的困境,并介紹功能安全標準中羅列的單元測試方法
    的頭像 發表于 11-03 14:58 ?1215次閱讀
    軟件<b class='flag-5'>單元測試</b>真的有必要嗎?(上)

    一種通用的汽車車身電子單元測試工裝的研究設計

    電子發燒友網站提供《一種通用的汽車車身電子單元測試工裝的研究設計.pdf》資料免費下載
    發表于 11-07 10:07 ?1次下載
    <b class='flag-5'>一種</b>通用的汽車車身電子<b class='flag-5'>單元測試</b>工裝的研究設計

    嵌入軟件單元測試工具的作用

    嵌入軟件單元測試工具是現代軟件開發過程中不可或缺的環。它的作用在于幫助開發人員對軟件中的各個單元進行測試,以確保其功能的正確性和穩定性。單元測試
    的頭像 發表于 04-23 15:31 ?678次閱讀
    嵌入軟件<b class='flag-5'>單元測試</b>工具的作用
    主站蜘蛛池模板: 上杭县| 榆林市| 巴彦县| 伊吾县| 大埔县| 和龙市| 鲁甸县| 新竹市| 肥西县| 日照市| 安龙县| 苗栗市| 吕梁市| 扶余县| 鞍山市| 肥东县| 时尚| 通辽市| 彩票| 尼玛县| 洱源县| 平利县| 靖边县| 衡南县| 苍山县| 普陀区| 鸡西市| 略阳县| 阿勒泰市| 泰安市| 东台市| 视频| 诸暨市| 忻州市| 尉氏县| 澄城县| 子长县| 神农架林区| 米易县| 本溪| 莱西市|