亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

如何使用Mockito調(diào)用靜態(tài)方法和void方法

 更新時(shí)間:2021年07月12日 11:17:07   作者:伯安樂(lè)  
這篇文章主要介紹了如何使用Mockito調(diào)用靜態(tài)方法和void方法的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

一、mock 靜態(tài)方法

mockito庫(kù)并不能mock靜態(tài)方法,需要依賴(lài)powermock

第一步:給類(lèi)添加注解

// 靜態(tài)類(lèi)優(yōu)先加載,所以需要提前告訴powermock哪些靜態(tài)類(lèi)需要mock
@ContextConfiguration
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
@PrepareForTest(靜態(tài)調(diào)用類(lèi).class)
public class SupplierServiceImplTest extends PowerMockTestCase {}

第二步:mock使用

@Test(expectedExceptions = BusinessException.class)
public void testAddSupplierAccount_genIdentityNoError() {
    // 告訴powermock,需要mock該類(lèi)的所有靜態(tài)方法
 PowerMockito.mockStatic(PasswordGenerator.class);
 
 final SupplierAccountDto supplierAccountDto = new SupplierAccountDto();
 supplierAccountDto.setName("小明");
 final String randomPWd = "666"; 
 PowerMockito.when(supplierDao.selectByEmail(anyString()))
   .thenReturn(new ArrayList<HaitaoSupplier>());
 // 靜態(tài)方法mock
 PowerMockito.when(PasswordGenerator.genPwd()).thenReturn(randomPWd);
 PowerMockito.when(pwEncoder.encode(anyString())).thenReturn(randomPWd);
 PowerMockito.when(identityNoGenerator.genIdentityNo()).thenReturn(-1L);
 
 supplierServiceImpl.addSupplierAccount(supplierAccountDto); 
 verify(pwEncoder).encode(randomPWd);
}

二、mock void 方法

// void嘛,doNothing顧名思義
PowerMockito.doNothing().when(casService).addSupplier(anyLong(), any(ServiceKey.class));

使用PowerMockito和Mockito進(jìn)行模擬測(cè)試

包括靜態(tài)方法測(cè)試,私有方法測(cè)試等,以及方法執(zhí)行的坑或者模擬不成功解決

一 普通spring項(xiàng)目

依賴(lài):這個(gè)很重要,不同版本用法也有點(diǎn)區(qū)別:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>2.0.2-beta</version>
    <scope>test</scope>
</dependency>
 
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito</artifactId>
    <version>1.7.4</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>2.0.0</version>
    <scope>test</scope>
</dependency>
 
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-core</artifactId>
    <version>1.7.4</version>
    <scope>test</scope>
</dependency>

接下來(lái)就是mock測(cè)試了,使用完全模擬測(cè)試過(guò)程,對(duì)于需要測(cè)試接口中調(diào)用的靜態(tài),私有方法等,返回自己想要的預(yù)期結(jié)果,達(dá)到測(cè)試效果:

這里有幾個(gè)要點(diǎn):

測(cè)試過(guò)程中完全手動(dòng)mock,不會(huì)真實(shí)調(diào)用或者產(chǎn)生數(shù)據(jù)

一 mock對(duì)象

order = mock(Order.class);
user = mock(User.class);

二 屬性注入

將service等類(lèi)中需要的其他service或者mapper等mock出來(lái),然后分別使用工具類(lèi)注入,名稱(chēng)保持一致即可

roomTypeService = mock(RoomTypeServiceImpl.class);
ticketComponetService = mock(TicketComponetServiceImpl.class);
hotelMapper = mock(HotelMapper.class);
//注入屬性
ReflectionTestUtils.setField(orderService, "hotelGroupMapper", hotelGroupMapper);
ReflectionTestUtils.setField(orderService, "dsUtils", dsUtils);
ReflectionTestUtils.setField(orderService, "orderMapper", orderMapper);

三 靜態(tài)方法mock

模擬靜態(tài)方法返回結(jié)果需要使用PowerMockit,測(cè)試類(lèi)上必須加注解@PrepareForTest

//account 獲取stub
PowerMockito.mockStatic(Account.class);
Mockito.when(Account.get(anyString(), anyString(), anyString(), anyInt())).thenReturn(account);

四 私有方法

私有方法首先需要在類(lèi)上加入注解,對(duì)于要測(cè)試的類(lèi)中的public方法同樣有效,比如測(cè)試方法中包含一個(gè)public方法,可以同樣模擬:

@PrepareForTest(ConsumptionServiceImpl.class)  //里面寫(xiě)需要模擬私有方法的類(lèi)class

然后對(duì)象不能mock,必須new一個(gè),并且需要用spy處理:

orderService = PowerMockito.spy(new OrderServiceImpl());

接著使用doreturn .when這種形式模式,不能使用先when后return這種,會(huì)報(bào)錯(cuò)

注意一點(diǎn),模擬參數(shù)要么全部模擬,要么全部自定義,不能混搭

這里有個(gè)大坑,如果出現(xiàn)私有方法還是進(jìn)去執(zhí)行的情況,很大可能是參數(shù)不對(duì),比如你mock的參數(shù)是 anyString(),那么你真是測(cè)試時(shí)候傳遞的必須是一個(gè)String實(shí)例,不能是null,否則mock就會(huì)失敗,我這里之前一直是對(duì)象的一個(gè)屬性,直接new了一個(gè)對(duì)象傳遞

所以一直不成功:

比如 方法需要的是user.getId() ,而且你mock的是一個(gè)anyInt(),那么真正傳遞的時(shí)候必須給這個(gè)user,setId(9527),否則就無(wú)法達(dá)成預(yù)期的模擬效果,所有方法都一樣!!

try {<br>        // 方法名,方法參數(shù),必須全部對(duì)應(yīng),否則報(bào)錯(cuò)方法找不到
     PowerMockito.doReturn(1).when(orderService, "dateListMinBook",anyString(),anyString(),any(RoomType.class),anyString(),anyString());
     PowerMockito.doReturn(ResponseMessage.success().pushData("dateRoomTypeList",new ArrayList<DateRoomType>())).when(orderService, "eachDateNumAndPrice",any(Order.class),any(RoomType.class),anyBoolean(),anyInt(),anyString(),any(User.class));
     PowerMockito.doReturn("2000").when(orderService, "getKeeptimeByWxcidAndHotelidAndLevel",anyString(),anyString(),anyString());
     PowerMockito.doNothing().when(orderService, "getPayWay",any(),any(),any(),any(),any());
 } catch (Exception e) {
     e.printStackTrace();
 }

五 預(yù)期結(jié)果

verify :判斷方法執(zhí)行了幾次: 確定測(cè)試是否通過(guò)

例如:verify(userService, times(1)).queryUser(any(anyInt(),anyString(),anyString());

二 springboot項(xiàng)目使用

1 依賴(lài)

<!-- S-junit -->
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <version>2.0.2-beta</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito2</artifactId>
            <version>2.0.0-beta.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>2.0.0-beta.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-core</artifactId>
            <version>2.0.0-RC.4</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.9</version>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-inline</artifactId>
            <version>2.15.0</version>
        </dependency>
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.12.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.easymock</groupId>
            <artifactId>easymock</artifactId>
            <version>4.0.2</version>
            <scope>test</scope>
        </dependency>
        <!-- E-junit -->

2 創(chuàng)建測(cè)試基類(lèi)

/**
 * 測(cè)試基類(lèi),所有子測(cè)試類(lèi)繼承此類(lèi)即可
 */
@PowerMockRunnerDelegate(SpringRunner.class)
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"javax.management.*", "javax.security.*"}) //忽略一些mock異常
@SpringBootTest
public class TestBase {
}

3 創(chuàng)建特定的測(cè)試類(lèi)

public class HotelControllerTest extends TestBase { //繼承基類(lèi)即可
    @Mock
    private HotelService hotelService;
    private Integer id;
//  加載springContext進(jìn)行mock測(cè)試,真實(shí)調(diào)用方法,不需要mock步驟
//     @Autowired
//     private HotelController hotelController;
//    純mock測(cè)試,不加載springContext,執(zhí)行mock操作,必須mock步驟,不會(huì)真實(shí)調(diào)用
    @InjectMocks
    private HotelController hotelController=new HotelController();
    // 應(yīng)用到所有門(mén)店測(cè)試
    @Test
    public void detailTest(){
        System.out.println("test start.....");
        // 1 構(gòu)造參數(shù)
        ininParams(1);
        // 2 mock步驟
        mockStep();
        // 3 執(zhí)行操作
        ResponseMessage result = hotelController.detail(id);
        System.out.println(new Gson().toJson(result));
        assertEquals(0, (int) result.getCode());
    }
    private void mockStep() {
        when(hotelService.detail(anyInt())).thenReturn(ResponseMessage.success());
    }
    private void ininParams(Integer type) {
        switch(type){
            case 1:
                id=17317;
                break;
            case 2:
                id=2;
                break;
            default:
                break;
        }
    }
}

4 模擬私有方法和靜態(tài)方法

@PrepareForTest(OrderServiceImpl.class)  // 需要調(diào)用私有或者靜態(tài)方法的類(lèi)
public class OrderControllerTest extends TestBase {
    private OrderServiceImpl orderServiceImpl; //需要調(diào)用私有或者靜態(tài)方法時(shí),不能使用@Mock,還需要@before初始化屬性
    @Mock
    private OrderMapper orderMapper;
    @Mock
    private RestTemplateUtil restTemplateUtil;
    private Integer orderId;
    private String wxcid;
    @Before
    public void init(){
        //處理私有方法模擬實(shí)例
        orderServiceImpl = PowerMockito.spy(new OrderServiceImpl()); //使用spy模擬的需要手動(dòng)注入屬性,因?yàn)槭裁炊紱](méi)有
        ReflectionTestUtils.setField(orderController, "iOrderService", orderServiceImpl);
        ReflectionTestUtils.setField(orderServiceImpl, "orderMapper", orderMapper);
        ReflectionTestUtils.setField(orderServiceImpl, "restTemplateUtil", restTemplateUtil);
    }
    //純mock測(cè)試,不加載springContext,執(zhí)行mock操作,必須mock步驟,不會(huì)真實(shí)調(diào)用
    @InjectMocks
    private OrderController orderController=new OrderController();
    @Test
    public void cancelTest(){
        System.out.println("test start.....");
        // 1 構(gòu)造參數(shù)
        ininParams();
        // 2 mock步驟
        mockStep();
        // 3 執(zhí)行操作
        ResponseMessage cancel = orderController.cancel(wxcid, orderId);
        assertEquals(0,(int)cancel.getCode());
    }
    private void mockStep() {
        Order order = new Order();
        order.setStatus(2);
        when(orderMapper.getOrderByOrderId(anyInt())).thenReturn(order);
        when(orderMapper.updateStatus(anyInt(),anyInt())).thenReturn(2);
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("code",0);
        when(restTemplateUtil.postToCri(anyString(),anyString(),any())).thenReturn(jsonObject);
        //處理私有方法,必須用這種寫(xiě)法
        try {
            PowerMockito.doNothing().when(orderServiceImpl, "returnTicketTouser", anyString(),any());
            PowerMockito.doReturn(ErrorCode.SUCCESS).when(orderServiceImpl, "refoundAndGetCode", any(),any(),any(),any());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void ininParams() {
        wxcid="57af462dff475fe4644de32f08406aa8";
        orderId=25864;
    }
}

注意:

如果是分模塊項(xiàng)目,springboot項(xiàng)目的啟動(dòng)類(lèi)只能有一個(gè),即需要把其他service,dao,common模塊的啟動(dòng)類(lèi)的啟動(dòng)注解給注釋掉,否則測(cè)試啟動(dòng)會(huì)報(bào)錯(cuò)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot中@ComponentScan的使用詳解

    SpringBoot中@ComponentScan的使用詳解

    這篇文章主要介紹了SpringBoot中@ComponentScan的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • MyBatis的JdbcType與Oracle、MySql數(shù)據(jù)類(lèi)型一覽表

    MyBatis的JdbcType與Oracle、MySql數(shù)據(jù)類(lèi)型一覽表

    這篇文章主要介紹了MyBatis的JdbcType與Oracle、MySql數(shù)據(jù)類(lèi)型一覽表,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • java Hibernate多對(duì)多映射詳解及實(shí)例代碼

    java Hibernate多對(duì)多映射詳解及實(shí)例代碼

    這篇文章主要介紹了java Hibernate多對(duì)多映射詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • Java中的Collections類(lèi)的使用示例詳解

    Java中的Collections類(lèi)的使用示例詳解

    Collections類(lèi)提供了一些靜態(tài)方法,這些方法能夠?qū)ist集合實(shí)現(xiàn)常用的算法操作,這些算法是排序,填充,移位和查找等。本文將通過(guò)示例為大家詳細(xì)講講Collections類(lèi)的使用,需要的可以參考一下
    2022-12-12
  • Java排序算法三之歸并排序的遞歸與非遞歸的實(shí)現(xiàn)示例解析

    Java排序算法三之歸并排序的遞歸與非遞歸的實(shí)現(xiàn)示例解析

    這篇文章主要介紹了Java排序算法三之歸并排序的遞歸與非遞歸的實(shí)現(xiàn)示例解析,文章通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • SpringBoot整合Hashids實(shí)現(xiàn)數(shù)據(jù)ID加密隱藏的全過(guò)程

    SpringBoot整合Hashids實(shí)現(xiàn)數(shù)據(jù)ID加密隱藏的全過(guò)程

    這篇文章主要為大家詳細(xì)介紹了SpringBoot整合Hashids實(shí)現(xiàn)數(shù)據(jù)ID加密隱藏的全過(guò)程,文中的示例代碼講解詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • Bean?Searcher配合SpringBoot的使用詳解

    Bean?Searcher配合SpringBoot的使用詳解

    這篇文章主要介紹了Bean?Searcher配合SpringBoot的使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • xxl-job對(duì)比ElasticJob使用示例詳解

    xxl-job對(duì)比ElasticJob使用示例詳解

    這篇文章主要為大家介紹了xxl-job對(duì)比ElasticJob使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • MyBatis中的連接池及事物控制配置過(guò)程

    MyBatis中的連接池及事物控制配置過(guò)程

    連接池就是用于存儲(chǔ)數(shù)據(jù)庫(kù)連接的一個(gè)容器,容器其實(shí)就是一個(gè)集合對(duì)象,本文給大家介紹MyBatis中的連接池以及事物控制的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2021-05-05
  • 使用Spring從YAML文件讀取內(nèi)容映射為Map方式

    使用Spring從YAML文件讀取內(nèi)容映射為Map方式

    這篇文章主要介紹了使用Spring從YAML文件讀取內(nèi)容映射為Map方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02

最新評(píng)論