1. 程式人生 > >Spring Boot 2 實踐記錄之 使用 Powermock、Mockito 對 UUID 進行 mock 單元測試

Spring Boot 2 實踐記錄之 使用 Powermock、Mockito 對 UUID 進行 mock 單元測試

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 單元測試