Spring Boot 2 實踐記錄之 使用 Powermock、Mockito 對 UUID 進行 mock 單元測試
阿新 • • 發佈:2019-02-24
alt 生成 digest md5 加密 調用 uuid tid 第一步 加密算
由於註冊時,需要對輸入的密碼進行加密,使用到了 UUID、sha1、md 等算法。在單元測試時,使用到了 Powermock,記錄如下。
先看下加密算法:
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.DigestUtils; import java.util.UUID; public class Encrypt { /** * 密碼加密 * @param password 待加密的密碼 * @param md5 是否先用 md5 加密 *@return 加密後的密碼 */ public static String passwordGenerator(String password) { password = DigestUtils.md5Hex(password); String salt = DigestUtils.sha1Hex(UUID.randomUUID().toString()).substring(0, 4); String saltString = DigestUtils.sha1Hex(password + salt) + salt; String encryPassword= Base64.encodeBase64String(saltString.getBytes()); return encryPassword; } }
其中,UUID.randomUUID()、DigestUtils.md5Hex()、DigestUtils.sha1Hex()、Base64.encodeBase64String() 均為靜態方法,而 uuid.toString() 則為 UUID 實例對象的方法。
對於 UUID 的 mock,需要兩步:
第一步,是使用 mockito mock 一個 UUID 對象,並 mock 其在代碼中使用的方法,這裏要 mock 的是 toString() 方法。
第二步,是使用 powormockito,mock UUID 的 randomUUID() 方法,使其返回上一步 mock 的 uuid 對象,這樣我們就能得到預期的 uuid 的方法(這裏是 toString)的執行結果。
DigestUtils 和 Base64 的靜態方法直接使用 powermockito 來 mock 就可以了。
具體步驟如下:
一、添加依賴包(使用 maven):
<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-api-mockito2</artifactId> <version>2.0.0</version> <scope>test</scope> </dependency>
二、在測試類上添加 @Runwith 和 @PrepareForTest 註解
三、在測試方法中對類和對象進行 mock。
示例代碼:
import org.apache.commons.codec.digest.DigestUtils; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.apache.commons.codec.binary.Base64; import java.util.UUID; import static org.junit.Assert.*; @RunWith(PowerMockRunner.class) @PrepareForTest({UUID.class, DigestUtils.class, Encrypt.class, Base64.class}) public class EncryptTest { @Test public void passwordGeneratorWithMd5() { String randomString = "mbaefaeq"; String salt = "abcd"; String password = "123456"; String rePassword = "654321"; String twiceSaltMd5 = "hellomd5"; // mock uuid 對象,使其 toString() 方法返回預定義的 randomString 字符串 UUID uuid = PowerMockito.mock(UUID.class); Mockito.when(uuid.toString()).thenReturn(randomString); // mock UUID 類,使其 randomUUID() 方法返回剛剛 mock 的 uuid 對象 PowerMockito.mockStatic(UUID.class); PowerMockito.when(UUID.randomUUID()).thenReturn(uuid); // mock DigestUtils 類,使其 sha1Hex() 方法在接收預定義的 randomString 參數時,返回預定義的 salt 字符串 PowerMockito.mockStatic(DigestUtils.class); PowerMockito.when(DigestUtils.sha1Hex(randomString)).thenReturn(salt); // 使 mock 的 DigestUtils 類的 md5Hex 方法,在接受預定義的 password 時,生成預定義的 rePassword 字符串 PowerMockito.when(DigestUtils.md5Hex(password)).thenReturn(rePassword); // 使 mock 的 DigestUtils 類的 sha1Hex() 方法在接收預定義的 rePassword 和 salt 時,返回 預定義的 twiceSaltMd5 字符串 PowerMockito.when(DigestUtils.sha1Hex(rePassword + salt)).thenReturn(twiceSaltMd5); // mock Base64 類,使其encodeBase64String() 方法在接收 預定義的串時,返回預定義的加密後密碼 PowerMockito.mockStatic(Base64.class); String imencryptpassword = "imencryptpasswordwithmd5"; PowerMockito.when(Base64.encodeBase64String((twiceSaltMd5 + salt).getBytes())).thenReturn(imencryptpassword); // 調用加密方法,並驗證結果 String encryptPassword = Encrypt.passwordGenerator("123456"); assertEquals(imencryptpassword, encryptPassword); } }
Spring Boot 2 實踐記錄之 使用 Powermock、Mockito 對 UUID 進行 mock 單元測試