测试类写法以及几种常用方式
目錄
- 為什么需要測試類
- 常用的jar包
- 測試模擬接口調用
- 測試Restful接口
- 通過Mock模擬方法調用結果
- 判讀方法調用次數
- 注意事項
為什么需要測試類
-
方便模擬驗證已完成功能
開發過程中,代碼完成之后,在正式提交測試之前,往往需要自己對功能進行自查,修改一些明顯的問題。但是有時候由于本地環境限制,實際流程和數據難以模擬,為了不影響其他模塊,我們可以只針對自己新增加的功能進行測試。這時可以使用測試類,針對自己的接口,模擬特定的數據和環境,將測試的接口返回值與預期返回值進行對比,完成驗證測試。
-
方便后期維護
由于項目開發過程中,經常有需求變更,有時候會有涉及范圍很廣的改動,有完善的測試類,可以在大面積改動的時候,檢查出一些明顯的問題,針對改動能對項目掌控的更好,節省測試時間,減少工作量。
常用的jar包
org.junit.* Junit4 框架
是通用的測試 java 程序的測試框架JUnit可以對Java代碼進行白盒測試。
org.junit.Assert.* 斷言,用于對比結果是否符合預期,用來判斷測試結果的常用框架
org.mockito.* mock
也叫打樁,用來模擬數據,模擬方法調用
下面以SpringBoot為例,展示下測試類的具體使用
測試模擬接口調用
有接口 TestService 參數為String name 返回結果是 "Hello " + name
@Service public class TestServiceImpl implements TestService {/*** 測試接口*/@Overridepublic String testInterface(String name) {return "Hello " + name;} }這是我們的測試類
@RunWith(SpringRunner.class) @ActiveProfiles("ut") @SpringBootTest public class SiteCacheTest extends BaseTest {@Autowiredprivate TestService testService ;@Testpublic void testInterface() {String result = testService.testInterface("Tom");Assert.assertEquals("Hello Tom", result );} }測試結果是運行成功,這是一個很簡單的例子,沒有復雜的參數和業務邏輯,接口內部也沒有對其他接口的調用。
在這個測試類中
@ActiveProfiles(“ut”) 表示該測試運行時使用的是 application-ut.properties配置文件,我們實際開發工作中,往往會有多個環境,可以給測試類指定環境,方便控制測試,以及防止測試數據對實際環境造成影響。
@SpringBootTest 該注解表示這個類是一個SpringBoot測試類
Assert.assertEquals(“Hello Tom”, result )
該方法接收兩個參數,前者為期望值,后者為實際值,如果不一致,會測試失敗
Assert還有很多類似的方法,常用的有
1 - Assert.fail()
讓測試直接出錯,拋出 AssertionError 。
2 - Assert.fail(String message)
讓測試直接出錯,并在拋出 AssertionError 時輸出 message 作為錯誤提示信息。
3 - Assert.assertNull(Object object)
猜測 object 為 null,如果不為 null ,拋出 AssertionError 。
4 - Assert.assertSame(Object expected, Object actual)
猜測 expected 對象和 actual 對象引用的是同一個對象。 如果不同,拋出 AssertionError 。
5 - Assert.assertNotSame(Object expected, Object actual)
猜測 expected 對象和 actual 對象引用不同的對象。 如果相同,拋出 AssertionError 。
6 - Assert.assertTrue(boolean condition)
猜測 condition 為 true 。 如果為 false ,拋出 AssertionError 。
7 - Assert.assertFalse(boolean condition)
猜測 condition 為 false 。 如果為 true , 拋出 AssertionError 。
8- Assert.assertEquals(long expected, long actual)
猜測兩個 long 類型 expected 和 actual 的值相等。 如果不相等,拋出 AssertionError 。
9 - Assert.assertNotEquals(long unexpected, long actual)
猜測兩個 long 類型 unexpected 和 actual 的值不相等。 如果相等,拋出 AssertionError 。
測試Restful接口
前后臺返利開發中,針對給前臺調用的接口,經常會有一些500錯誤等,可以模擬請求,根據接口路徑來模擬前端調用
通常會傳一些錯誤參數來驗證返回錯誤信息的情況。
如上,我們傳正常的參數時,期望返回200, 即 MockMvcResultMatchers.status().isOk()
傳參數錯誤時返回 500, 即MockMvcResultMatchers.status().isInternalServerError()
在這個測試類中
首先需要引入WebApplicationContext 用來模擬前臺接口調用
@Before 該注解注解的方法,會在測試運行之前先運行,一般用于準備測試數據,初始化對象等,在此例中,我們用來初始化測試用的MockMvc 對象。
@Autowired 測試類可以像正常的類一樣,注入你所需要的對象
MockMvcRequestBuilders 來指定測試接口路徑,以及請求方式
.andExpect 類似斷言, 來指定期望值。
通過Mock模擬方法調用結果
在開發過程中,類都不是獨立的,往往一個方法的實現,需要調用多個不同地方的方法組合來實現一個功能,在測試中,我們需要其他方法的返回值滿足我們的測試需要,這個時候可以使用@Spy注解來包裝某個類,控制它的方法返回值。
下面看例子
在這個測試類中,testService中存在一個方法getUUID(),是返回隨機id的,但是在我們要測試的方法中調用了這個方法,我們需要用到這個uuid,來模擬數據,以便測試我們的接口,比如我們需要根據它去另外一張表查詢數據,但是我們不知道調用時隨機的uuid是什么,這時候可以指定它的返回值,當testService.getUUID()被調用時,返回一個指定的值,這樣我們就可以繼續操作了。
@Spy 對一個注入的類進行包裝,以便可以模擬方法返回值
我們需要使用 MockitoAnnotations.initMocks(this); 來初始化對象,該方法會對使用了**@Spy**的類進行初始化。
然后我們可以針對初始化過的對象來模擬返回值。
Mockito.when(xxx).thenReturn(xxx);
從字面可以看出,當…的時候返回…
需要注意的是when(…) thenReturn(…)會調用真實的方法,如果你不想調用真實的方法而是想要mock的話
就使用 doReturn(…) when(…) 不會調用真實方法
判讀方法調用次數
有些時候針對循環和和判斷較多,或者業務邏輯較為復雜的場景,需要判斷方法調用次數。 還有一個場景是判斷緩存是否生效,對于加了緩存的方法,多次調用,一般只有一次實際的調用,可以用這個方法來判斷調用次數。
@RunWith(SpringRunner.class) @ActiveProfiles("ut") @SpringBootTest public class CallTimesTest {@MockBeanprivate TestDao testDao;@Autowiredprivate TestService testService;@Testpublic void testCallTimes() {//設置第一次返回,第二次返回when(testDao.findUserByName(1)).thenReturn("user1").thenReturn("user2");String user1 = testService.findUserByName(1);Assert.assertEquals("user1", user1);String user2 = testService.findUserByName(1);Assert.assertEquals("user1", user1);verify(testDao, times(1)).findWithFullNameByTaskId(1);}假設 testService 的findUserByName 方法內部是調用的 testDao的findUserByName方法,我們首先使用**@MockBean** 注解 注解testDao ,對其進行包裝,然后我們可以對其進行模擬 ,設置第一次調用返回user1,第二次調用返回user2, 然后testService調用兩次,如果在testDao的findUserByName方法上加了緩存,那么對于同樣的入參,實際上只會調用一次。
我們可以使用verify來驗證方法調用次數。
需要注意的是,findUserByName 方法這里我們的入參是1,在mock中我們有時候不需要寫死參數,而是符合一定條件的參數即可,mock提供了一系列方法指定參數,如下圖
注意事項
- 測試要注意覆蓋率,不要只測試正確的情況,也要測試異常的情況
- 要模擬方法調,設定返回值需要先對類進行包裝,@Mock 和@Spy注解均可以實現,區別在于前者是虛假的調用,而且不能mock自動裝配的Bean,需要和@InjectMock配合使用;而后者監測真實的調用,方法實際上真的調用了,使用時要注意,想要不調用,可以使doReturn(…) when(…)。
- 在maven項目中,不設置skiptest=true的話,在打包時會默認先執行一遍測試類,所以要注意設置測試類運行環境,以免測試數據對正式環境造成污染,導致不必要的錯誤,更為規范的做法是,在每個測試用例中,最后對測試數據進行刪除。
總結
以上是生活随笔為你收集整理的测试类写法以及几种常用方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PDF如何排版骑马钉打印
- 下一篇: 数字条纹投影系统中基于概率分布函数的灵活