摘要:單元測試因為公司單元測試覆蓋率需要達到,所以進行單元測試用例編寫。測試的時候可以把每個判斷分支都走到。同這句代碼,可以通過如此一個對象,使用以上方法基本上可以編寫所有代碼的測試類。編寫測試一定程度上可以發現代碼錯誤,可以借此重構代碼。
3.springboot單元測試
因為公司單元測試覆蓋率需要達到80%,所以進行單元測試用例編寫。多模塊項目的因為會經常調用其他服務,而且避免數據庫操作對于數據庫造成影響,所以所有的操作都要mock掉,也就是模擬調用的結果。測試用例編寫可以參考https://www.journaldev.com/21...,上面介紹也比較詳細,不過以下介紹是自己遇到的一些問題。
3.1配置文件
6.14.3 4.12 2.19.0 2.0.0-beta.5 org.springframework.boot spring-boot-starter-test test org.testng testng ${testng.version} test junit junit ${junit4.version} test org.mockito mockito-core ${mockito-core.version} test org.powermock powermock-module-testng ${powermock.version} test org.powermock powermock-module-junit4 ${powermock.version} test org.powermock powermock-api-mockito2 ${powermock.version} test
可以參考如https://www.journaldev.com/21...
這三個依賴是支持靜態類mock所需要的,還有一個版本的問題,之前
java.lang.NoSuchMethodError: org.mockito.internal.handler.MockHandlerFactory.createMockHandler(Lorg/mockito/mock/MockCreationSettings;)Lorg/mockito/internal/InternalMockHandler;
的報錯,修改了版本后來得到了解決。
3.2.沒有靜態方法調用
要測的serverImpl類使用@InjectMocks,其他所有的依賴的類使用@Mock掉,這樣可以模擬依賴的類的實現而不是調用依賴類的實現,放置比如調用數據庫操作導致的問題。類上使用@RunWith(SpringRunner.class)注解。
一下為測試代碼,withLearningService.getGift(passId, code, token, ip)里面會用到paramUtil.getParamByParamName(PRODUCT_CODE)以及openApiService.userQueryInfoById(anyString()),所以我們需要把用到的兩個方法模擬它的返回結果。
when(paramUtil.getParamByParamName(PRODUCT_CODE)).thenReturn(productCode); when(openApiService.userQueryInfoById(anyString())).thenReturn(intevee); withLearningService.getGift(passId, code, token, ip);
使用when模擬paramUtil的返回結果,也可以使用any()模擬對象,anyString()來字符串,還有anyInt(),anyLong()模擬其他類型參數。測試的時候可以把每個判斷分支都走到。
如果類加上@SpringBootTest注解的話項目會啟動springboot項目加載各種配置,速度會慢很多,建議直接都mock掉不需要啟動springboot環境。
3.3需要使用靜態方法
類上使用
@RunWith(PowerMockRunner.class)
@PrepareForTest({ HttpsUtils.class, RedisUtil.class, SpringContextUtil.class,AESUtil.class,KeyGenerator.class })
兩個注解,需要使用靜態方法的類添加到@PrepareForTest的參數里面。一般的靜態方法調用直接使用:
PowerMockito.mockStatic(RedisUtil.class); PowerMockito.when(RedisUtil.get(anyString())).thenReturn("0");
但是如上面的這個調用會產生類似:
的錯誤,RedisUtil是我司自己封裝的Redis操作工具類,查看RedisUtil.get方法,看到需要注入spring的上下文環境ApplicationContext applicationContext。所以需要添加該上下文環境
PowerMockito.mockStatic(SpringContextUtil.class); PowerMockito.when(SpringContextUtil.getApplicationContext()).thenReturn(new XmlWebApplicationContext()); PowerMockito.mockStatic(RedisUtil.class); PowerMockito.when(RedisUtil.get(anyString())).thenReturn("0");
這樣可以解決問題,我自己編寫的過程中遇到了一個加解密類報錯,工具類代碼如下
if (key == null || content == null || content.isEmpty()) { return null; } String msg = null; byte[] byteRresult = new byte[content.length() / 2]; for (int i = 0; i < content.length() / 2; i++) { int high = Integer.parseInt(content.substring(i * 2, i * 2 + 1), 16); int low = Integer.parseInt(content.substring(i * 2 + 1, i * 2 + 2), 16); byteRresult[i] = (byte) (high * 16 + low); } try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128); SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); byte[] result = cipher.doFinal(byteRresult); return new String(result);
測試類的mock編寫如入下:
PowerMockito.mockStatic(AESUtil.class); PowerMockito.when(AESUtil.decrypt(anyString(), anyString())).thenReturn("11");
這樣編寫報錯,改為以下則完成測試用例編寫。
PowerMockito.mockStatic(KeyGenerator.class); KeyGenerator keyg = Mockito.mock(KeyGenerator.class); PowerMockito.when(KeyGenerator.getInstance(anyString())).thenReturn(keyg); PowerMockito.mockStatic(AESUtil.class); PowerMockito.when(AESUtil.decrypt(anyString(), anyString())).thenReturn("11");
同KeyGenerator keyg = Mockito.mock(KeyGenerator.class);這句代碼,可以通過如此mock一個對象,使用以上方法基本上可以編寫所有代碼的測試類。這里的測試最好都是針對server層進行測試,為什么不對controller層也進行測試,其實主要是單元測試的意義是把基本的邏輯跑通,controller層的測試一定程度上可以交由測試進行測試,單元測試如果要覆蓋到每一個判斷分支也是不好寫的,比較痛苦。編寫測試一定程度上可以發現代碼錯誤,可以借此重構代碼。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74307.html
摘要:熱加載代表的是我們不需要重啟服務器,就能夠類檢測得到,重新生成類的字節碼文件無論是熱部署或者是熱加載都是基于類加載器來完成的。驗證階段字節碼文件不會對造成危害準備階段是會賦初始值,并不是程序中的值。 一、SpringBoot入門 今天在慕課網中看見了Spring Boot這么一個教程,這個Spring Boot作為JavaWeb的學習者肯定至少會聽過,但我是不知道他是什么玩意。 只是大...
摘要:本博客貓叔的博客,轉載請申明出處本系列教程為項目附帶。歷史文章如何在安裝最新版安裝安裝最新版的入門教程的入門教程安裝教程安裝流程安裝如果不清楚是什么,請查看的文檔和簡介,這里給出的安裝過程安裝虛擬機如果有遠程服務器的,請略過此步驟本文推 本博客 貓叔的博客,轉載請申明出處本系列教程為HMStrange項目附帶。 Auth:HMStrange-TIAN e-mail:zhangqihao...
摘要:這里有一個參數,主要是用來指定該配置項在配置文件中的前綴。創建一個配置類,里面沒有顯式聲明任何的,然后將剛才創建的導入。創建實現類,返回的全類名。創建實現類,實現方法直接手動注冊一個名叫的到容器中。前言 小伙伴們是否想起曾經被 SSM 整合支配的恐懼?相信很多小伙伴都是有過這樣的經歷的,一大堆配置問題,各種排除掃描,導入一個新的依賴又得添加新的配置。自從有了 SpringBoot 之后,咋...
閱讀 1386·2019-08-30 12:54
閱讀 1870·2019-08-30 11:16
閱讀 1613·2019-08-30 10:50
閱讀 2449·2019-08-29 16:17
閱讀 1266·2019-08-26 12:17
閱讀 1378·2019-08-26 10:15
閱讀 2387·2019-08-23 18:38
閱讀 785·2019-08-23 17:50