日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

在真實的測試當中,并不能所有的邏輯都可以自己控制,因此有了mock測試。今天就結合場景來講一下怎么做mock測試。

適合對象:初次嘗試集成和使用mockito進行單元測試的開發同學

Spring的Mock測試你用上了嗎?

 

Mock框架的集成

這里選擇的是Mockito + PowerMockito。為什么會集成PowerMockito,是因為有個想要mock的方法是static方法。這個需要PowerMockito,假如都只是普通類,就可以不用了。

集成關鍵點如下

1、版本對應:這兩個mockito的版本是有一個對應關系,假如不對應,會出現類找不到的情況。比如 ClassNotFound org/mockito/mockitoframework 。而網上也已經有對應關系如下鏈接

https://github.com/powermock/powermock/wiki/Mockito#supported-versions

這是我的集成版本

<dependency>
		<groupId>org.mockito</groupId>
		<artifactId>mockito-core</artifactId>
		<version>2.28.2</version>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.powermock</groupId>
		<artifactId>powermock-module-junit4</artifactId>
		<version>2.0.2</version>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.powermock</groupId>
		<artifactId>powermock-api-mockito2</artifactId>
		<version>2.0.2</version>
		<scope>test</scope>
	</dependency>

2、注解方式集成:因為使用spring boot的項目,所以考慮怎么用注解方式集成。最后我的注解方案如下所示

@RunWith(PowerMockRunner.class)
@PrepareForTest({JdbcClient.class})
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
@PowerMockIgnore({"JAVAx.net.ssl.*","javax.management.*", "javax.security.*", "javax.crypto.*"})

這幾個,都有自己的用處,分別說下:

  • @RunWith(PowerMockRunner.class) :假如要使用powermock,那就需要配置這個,不然powermock無法使用
  • @PrepareForTest({JdbcClient.class}) :這里的列表,設定的是需要static mock 的類,我的測試場景中,需要mock JdbcClient的static query 方法
  • @PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class) : 一開始,只配置了前兩個,然后發現從spring中inject注入的service都為空了。原來要需要使用這個注解,這樣就和spring test 組合上了
  • @PowerMockIgnore({"javax.net.ssl.*","javax.management.*","javax.security.*","javax.crypto.*"}) :PowerMock大概是mock的太多了,所以假如沒有這行注釋,也是各種報錯。 ClassCastException: class sun.security.provider.ConfigFile 這種。

TIPS:這些注解可以寫到一個abstract TestClass 上,后面的測試類繼承這個就方便了

Mock場景舉例

好,正式開始mock。首先來講,網上那些例子,好多都太簡單了,不能當做實際場景。比如mock ClassA.method1,然后直接驗證method1的結果。這種只能驗證集成的對不對。還是結合真實場景比較好。

場景一:修改外部服務調用,比如調用支付寶支付,或者發個短信什么的,也可以是數據庫查詢

有時候,我們不希望真的去調用外部(比如配置太復雜,比如收費,比如想模擬錯誤結果)。或者想自己控制數據庫查詢結果(或者遇到了我這邊只有正式環境才有某個庫的情況)。那這時候,就需要使用Mock Service來解決。

先擼代碼,再分析。

這個場景講解mock的常規使用手法
以及在spring注入service情況下,如何處理mock

public class MockitoTest extends BaseTest {

    @Autowired
    DemoService demoService;

    @Mock
    RemoteService remoteService;

    @Test
    public void testHack() throws Exception {

        demoService.setRemoteService(remoteService);

        String result = "fail";
        Mockito.when(remoteService.sendRequest(any())).thenReturn(result);

        String callResult = demoService.callRemote("something");
        assertEquals("fail", callResult);

        Mockito.verify(remoteService).sendRequest(any());
    }
}

這個場景感覺用的挺多的。demoService是想要測試的功能,其中用到了remoteService.sendRequest的結果。而又不想實際調用remoteService。這時候就可以先把remoteService.sendRequest給mock掉,給出自己設定的返回結果。

這時候要注意的一個點是:remoteService并不歸屬springContext管理,所以run test 以后,會發現,這個mock毫無作用。debug之下,可以看到注入和mock的remoteService并不是一個實例。

那如何使remoteSerivce變成mockService,這里有兩個思路。

一、就是上面的方案,用mockSerivce去替換demoSerivce里的remoteService。

demoService.setRemoteService(remoteService);

二、替換springContext里面的remoteSerice,這就需要使用@MockBean 這個注解。 然后,所有注入的remoteService,都是Mock生成的service

    @MockBean
    RemoteService remoteService;

但是據說MockBean有副作用,會多次重啟Spring context。可能也會污染上下文。暫時沒有去嘗試研究。

場景二:修改靜態類方法,比如一些單例的方法。

在我的場景里,是自定義了一個單例JdbcClient,client保存連接池,然后發起請求。

這個是使用PowerMockito,因為只有他能mock static方法

先來代碼

public class MockitoTest extends BaseTest { 

    @Autowired
    DemoService demoService;


    @Test
    public void testHack() throws Exception {


        String result = "fail";
        PowerMockito.mockStatic(JdbcClient.class);
        Mockito.when(JdbcClient.sendRequest(any())).thenReturn(result);

        String callResult = demoService.callRemote("something");
        assertEquals("fail", callResult);
    }
}

這里的主要用法就是 PowerMockito.mockStatic 這個。但是要結合之前的兩個注解,@RunWith(PowerMockRunner.class) @PrepareForTest({JdbcClient.class}) 這個使用才有效

就寫這兩個場景吧。后續用到比較好的場景再補充,也歡迎大家提供更多使用場景一起學習學習。

分享到:
標簽:測試 Mock
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定