zoukankan      html  css  js  c++  java
  • Spring Boot 2 实践记录之 使用 Powermock、Mockito 对 UUID 进行 mock 单元测试

    由于注册时,需要对输入的密码进行加密,使用到了 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);
        }
    }
  • 相关阅读:
    [HAOI2015]树上染色 [树形dp]
    【luogu1052】 过河 [动态规划]
    【luogu4819】 [中山市选]杀人游戏 [tarjan 缩点]
    【luogu4185】 [USACO18JAN]MooTube [并查集]
    [国家集训队]墨墨的等式 [差分约束]
    【RMQ】
    [USACO05DEC] 布局 [差分约束]
    [SCOI2011]糖果 [差分约束]
    【POJ 1201】Intervals
    【luogu1993】 小K的农场 [差分约束]
  • 原文地址:https://www.cnblogs.com/matchless/p/10425639.html
Copyright © 2011-2022 走看看