Commit d897f8fb103945b4ad679079dfe969120c8e192c

Authored by YunaiV
1 parent a332d5f8

完善 SmsCodeServiceImpl 单元测试

Showing 11 changed files with 253 additions and 29 deletions
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApi.java
1 package cn.iocoder.yudao.module.system.api.sms; 1 package cn.iocoder.yudao.module.system.api.sms;
2 2
3 import cn.iocoder.yudao.framework.common.exception.ServiceException; 3 import cn.iocoder.yudao.framework.common.exception.ServiceException;
4 -import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeCheckReqDTO; 4 +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO;
5 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; 5 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
6 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; 6 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
7 7
@@ -35,6 +35,6 @@ public interface SmsCodeApi { @@ -35,6 +35,6 @@ public interface SmsCodeApi {
35 * 35 *
36 * @param reqDTO 校验请求 36 * @param reqDTO 校验请求
37 */ 37 */
38 - void checkSmsCode(@Valid SmsCodeCheckReqDTO reqDTO); 38 + void validateSmsCode(@Valid SmsCodeValidateReqDTO reqDTO);
39 39
40 } 40 }
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/code/SmsCodeCheckReqDTO.java renamed to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/code/SmsCodeValidateReqDTO.java
@@ -14,7 +14,7 @@ import javax.validation.constraints.NotNull; @@ -14,7 +14,7 @@ import javax.validation.constraints.NotNull;
14 * @author 芋道源码 14 * @author 芋道源码
15 */ 15 */
16 @Data 16 @Data
17 -public class SmsCodeCheckReqDTO { 17 +public class SmsCodeValidateReqDTO {
18 18
19 /** 19 /**
20 * 手机号 20 * 手机号
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApiImpl.java
1 package cn.iocoder.yudao.module.system.api.sms; 1 package cn.iocoder.yudao.module.system.api.sms;
2 2
3 -import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeCheckReqDTO; 3 +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO;
4 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; 4 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
5 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; 5 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
6 import cn.iocoder.yudao.module.system.service.sms.SmsCodeService; 6 import cn.iocoder.yudao.module.system.service.sms.SmsCodeService;
@@ -32,8 +32,8 @@ public class SmsCodeApiImpl implements SmsCodeApi { @@ -32,8 +32,8 @@ public class SmsCodeApiImpl implements SmsCodeApi {
32 } 32 }
33 33
34 @Override 34 @Override
35 - public void checkSmsCode(SmsCodeCheckReqDTO reqDTO) {  
36 - smsCodeService.checkSmsCode(reqDTO); 35 + public void validateSmsCode(SmsCodeValidateReqDTO reqDTO) {
  36 + smsCodeService.validateSmsCode(reqDTO);
37 } 37 }
38 38
39 } 39 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeService.java
1 package cn.iocoder.yudao.module.system.service.sms; 1 package cn.iocoder.yudao.module.system.service.sms;
2 2
3 import cn.iocoder.yudao.framework.common.exception.ServiceException; 3 import cn.iocoder.yudao.framework.common.exception.ServiceException;
4 -import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeCheckReqDTO; 4 +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO;
5 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; 5 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
6 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; 6 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
7 7
@@ -35,6 +35,6 @@ public interface SmsCodeService { @@ -35,6 +35,6 @@ public interface SmsCodeService {
35 * 35 *
36 * @param reqDTO 校验请求 36 * @param reqDTO 校验请求
37 */ 37 */
38 - void checkSmsCode(@Valid SmsCodeCheckReqDTO reqDTO); 38 + void validateSmsCode(@Valid SmsCodeValidateReqDTO reqDTO);
39 39
40 } 40 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImpl.java
@@ -3,11 +3,9 @@ package cn.iocoder.yudao.module.system.service.sms; @@ -3,11 +3,9 @@ package cn.iocoder.yudao.module.system.service.sms;
3 import cn.hutool.core.date.LocalDateTimeUtil; 3 import cn.hutool.core.date.LocalDateTimeUtil;
4 import cn.hutool.core.lang.Assert; 4 import cn.hutool.core.lang.Assert;
5 import cn.hutool.core.map.MapUtil; 5 import cn.hutool.core.map.MapUtil;
6 -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;  
7 -import cn.iocoder.yudao.framework.common.util.date.DateUtils;  
8 -import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeCheckReqDTO;  
9 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; 6 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
10 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; 7 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
  8 +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO;
11 import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO; 9 import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO;
12 import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsCodeMapper; 10 import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsCodeMapper;
13 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; 11 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
@@ -16,11 +14,11 @@ import org.springframework.stereotype.Service; @@ -16,11 +14,11 @@ import org.springframework.stereotype.Service;
16 import org.springframework.validation.annotation.Validated; 14 import org.springframework.validation.annotation.Validated;
17 15
18 import javax.annotation.Resource; 16 import javax.annotation.Resource;
19 -  
20 import java.time.LocalDateTime; 17 import java.time.LocalDateTime;
21 -import java.time.temporal.ChronoUnit;  
22 18
23 import static cn.hutool.core.util.RandomUtil.randomInt; 19 import static cn.hutool.core.util.RandomUtil.randomInt;
  20 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  21 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.isToday;
24 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; 22 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
25 23
26 /** 24 /**
@@ -58,11 +56,11 @@ public class SmsCodeServiceImpl implements SmsCodeService { @@ -58,11 +56,11 @@ public class SmsCodeServiceImpl implements SmsCodeService {
58 if (lastSmsCode != null) { 56 if (lastSmsCode != null) {
59 if (LocalDateTimeUtil.between(lastSmsCode.getCreateTime(), LocalDateTime.now()).toMillis() 57 if (LocalDateTimeUtil.between(lastSmsCode.getCreateTime(), LocalDateTime.now()).toMillis()
60 < smsCodeProperties.getSendFrequency().toMillis()) { // 发送过于频繁 58 < smsCodeProperties.getSendFrequency().toMillis()) { // 发送过于频繁
61 - throw ServiceExceptionUtil.exception(SMS_CODE_SEND_TOO_FAST); 59 + throw exception(SMS_CODE_SEND_TOO_FAST);
62 } 60 }
63 - if (DateUtils.isToday(lastSmsCode.getCreateTime()) && // 必须是今天,才能计算超过当天的上限 61 + if (isToday(lastSmsCode.getCreateTime()) && // 必须是今天,才能计算超过当天的上限
64 lastSmsCode.getTodayIndex() >= smsCodeProperties.getSendMaximumQuantityPerDay()) { // 超过当天发送的上限。 62 lastSmsCode.getTodayIndex() >= smsCodeProperties.getSendMaximumQuantityPerDay()) { // 超过当天发送的上限。
65 - throw ServiceExceptionUtil.exception(SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY); 63 + throw exception(SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY);
66 } 64 }
67 // TODO 芋艿:提升,每个 IP 每天可发送数量 65 // TODO 芋艿:提升,每个 IP 每天可发送数量
68 // TODO 芋艿:提升,每个 IP 每小时可发送数量 66 // TODO 芋艿:提升,每个 IP 每小时可发送数量
@@ -71,7 +69,7 @@ public class SmsCodeServiceImpl implements SmsCodeService { @@ -71,7 +69,7 @@ public class SmsCodeServiceImpl implements SmsCodeService {
71 // 创建验证码记录 69 // 创建验证码记录
72 String code = String.valueOf(randomInt(smsCodeProperties.getBeginCode(), smsCodeProperties.getEndCode() + 1)); 70 String code = String.valueOf(randomInt(smsCodeProperties.getBeginCode(), smsCodeProperties.getEndCode() + 1));
73 SmsCodeDO newSmsCode = SmsCodeDO.builder().mobile(mobile).code(code).scene(scene) 71 SmsCodeDO newSmsCode = SmsCodeDO.builder().mobile(mobile).code(code).scene(scene)
74 - .todayIndex(lastSmsCode != null && DateUtils.isToday(lastSmsCode.getCreateTime()) ? lastSmsCode.getTodayIndex() + 1 : 1) 72 + .todayIndex(lastSmsCode != null && isToday(lastSmsCode.getCreateTime()) ? lastSmsCode.getTodayIndex() + 1 : 1)
75 .createIp(ip).used(false).build(); 73 .createIp(ip).used(false).build();
76 smsCodeMapper.insert(newSmsCode); 74 smsCodeMapper.insert(newSmsCode);
77 return code; 75 return code;
@@ -80,32 +78,32 @@ public class SmsCodeServiceImpl implements SmsCodeService { @@ -80,32 +78,32 @@ public class SmsCodeServiceImpl implements SmsCodeService {
80 @Override 78 @Override
81 public void useSmsCode(SmsCodeUseReqDTO reqDTO) { 79 public void useSmsCode(SmsCodeUseReqDTO reqDTO) {
82 // 检测验证码是否有效 80 // 检测验证码是否有效
83 - SmsCodeDO lastSmsCode = this.checkSmsCode0(reqDTO.getMobile(), reqDTO.getCode(), reqDTO.getScene()); 81 + SmsCodeDO lastSmsCode = validateSmsCode0(reqDTO.getMobile(), reqDTO.getCode(), reqDTO.getScene());
84 // 使用验证码 82 // 使用验证码
85 smsCodeMapper.updateById(SmsCodeDO.builder().id(lastSmsCode.getId()) 83 smsCodeMapper.updateById(SmsCodeDO.builder().id(lastSmsCode.getId())
86 .used(true).usedTime(LocalDateTime.now()).usedIp(reqDTO.getUsedIp()).build()); 84 .used(true).usedTime(LocalDateTime.now()).usedIp(reqDTO.getUsedIp()).build());
87 } 85 }
88 86
89 @Override 87 @Override
90 - public void checkSmsCode(SmsCodeCheckReqDTO reqDTO) {  
91 - checkSmsCode0(reqDTO.getMobile(), reqDTO.getCode(), reqDTO.getScene()); 88 + public void validateSmsCode(SmsCodeValidateReqDTO reqDTO) {
  89 + validateSmsCode0(reqDTO.getMobile(), reqDTO.getCode(), reqDTO.getScene());
92 } 90 }
93 91
94 - public SmsCodeDO checkSmsCode0(String mobile, String code, Integer scene) { 92 + private SmsCodeDO validateSmsCode0(String mobile, String code, Integer scene) {
95 // 校验验证码 93 // 校验验证码
96 SmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, code, scene); 94 SmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, code, scene);
97 // 若验证码不存在,抛出异常 95 // 若验证码不存在,抛出异常
98 if (lastSmsCode == null) { 96 if (lastSmsCode == null) {
99 - throw ServiceExceptionUtil.exception(SMS_CODE_NOT_FOUND); 97 + throw exception(SMS_CODE_NOT_FOUND);
100 } 98 }
101 // 超过时间 99 // 超过时间
102 if (LocalDateTimeUtil.between(lastSmsCode.getCreateTime(), LocalDateTime.now()).toMillis() 100 if (LocalDateTimeUtil.between(lastSmsCode.getCreateTime(), LocalDateTime.now()).toMillis()
103 >= smsCodeProperties.getExpireTimes().toMillis()) { // 验证码已过期 101 >= smsCodeProperties.getExpireTimes().toMillis()) { // 验证码已过期
104 - throw ServiceExceptionUtil.exception(SMS_CODE_EXPIRED); 102 + throw exception(SMS_CODE_EXPIRED);
105 } 103 }
106 // 判断验证码是否已被使用 104 // 判断验证码是否已被使用
107 if (Boolean.TRUE.equals(lastSmsCode.getUsed())) { 105 if (Boolean.TRUE.equals(lastSmsCode.getUsed())) {
108 - throw ServiceExceptionUtil.exception(SMS_CODE_USED); 106 + throw exception(SMS_CODE_USED);
109 } 107 }
110 return lastSmsCode; 108 return lastSmsCode;
111 } 109 }
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.service.sms;
  2 +
  3 +import cn.hutool.core.map.MapUtil;
  4 +import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants;
  5 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  6 +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
  7 +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
  8 +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO;
  9 +import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO;
  10 +import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsCodeMapper;
  11 +import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
  12 +import cn.iocoder.yudao.module.system.framework.sms.SmsCodeProperties;
  13 +import com.baomidou.mybatisplus.annotation.DbType;
  14 +import org.junit.jupiter.api.BeforeEach;
  15 +import org.junit.jupiter.api.Test;
  16 +import org.springframework.boot.test.mock.mockito.MockBean;
  17 +import org.springframework.context.annotation.Import;
  18 +
  19 +import javax.annotation.Resource;
  20 +import java.time.Duration;
  21 +import java.time.LocalDateTime;
  22 +
  23 +import static cn.hutool.core.util.RandomUtil.randomEle;
  24 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  25 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  26 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  27 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
  28 +import static org.junit.jupiter.api.Assertions.*;
  29 +import static org.mockito.ArgumentMatchers.eq;
  30 +import static org.mockito.ArgumentMatchers.isNull;
  31 +import static org.mockito.Mockito.verify;
  32 +import static org.mockito.Mockito.when;
  33 +
  34 +@Import(SmsCodeServiceImpl.class)
  35 +public class SmsCodeServiceImplTest extends BaseDbUnitTest {
  36 +
  37 + @Resource
  38 + private SmsCodeServiceImpl smsCodeService;
  39 +
  40 + @Resource
  41 + private SmsCodeMapper smsCodeMapper;
  42 +
  43 + @MockBean
  44 + private SmsCodeProperties smsCodeProperties;
  45 + @MockBean
  46 + private SmsSendService smsSendService;
  47 +
  48 + @BeforeEach
  49 + public void setUp() {
  50 + when(smsCodeProperties.getExpireTimes()).thenReturn(Duration.ofMinutes(5));
  51 + when(smsCodeProperties.getSendFrequency()).thenReturn(Duration.ofMinutes(1));
  52 + when(smsCodeProperties.getSendMaximumQuantityPerDay()).thenReturn(10);
  53 + when(smsCodeProperties.getBeginCode()).thenReturn(9999);
  54 + when(smsCodeProperties.getEndCode()).thenReturn(9999);
  55 + }
  56 +
  57 + @Test
  58 + public void sendSmsCode_success() {
  59 + // 准备参数
  60 + SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
  61 + o.setMobile("15601691300");
  62 + o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene());
  63 + });
  64 + // mock 方法
  65 + SqlConstants.init(DbType.MYSQL);
  66 +
  67 + // 调用
  68 + smsCodeService.sendSmsCode(reqDTO);
  69 + // 断言 code 验证码
  70 + SmsCodeDO smsCodeDO = smsCodeMapper.selectOne(null);
  71 + assertPojoEquals(reqDTO, smsCodeDO);
  72 + assertEquals("9999", smsCodeDO.getCode());
  73 + assertEquals(1, smsCodeDO.getTodayIndex());
  74 + assertFalse(smsCodeDO.getUsed());
  75 + // 断言调用
  76 + verify(smsSendService).sendSingleSms(eq(reqDTO.getMobile()), isNull(), isNull(),
  77 + eq("user-sms-login"), eq(MapUtil.of("code", "9999")));
  78 + }
  79 +
  80 + @Test
  81 + public void sendSmsCode_tooFast() {
  82 + // mock 数据
  83 + SmsCodeDO smsCodeDO = randomPojo(SmsCodeDO.class,
  84 + o -> o.setMobile("15601691300").setTodayIndex(1));
  85 + smsCodeMapper.insert(smsCodeDO);
  86 + // 准备参数
  87 + SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
  88 + o.setMobile("15601691300");
  89 + o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene());
  90 + });
  91 + // mock 方法
  92 + SqlConstants.init(DbType.MYSQL);
  93 +
  94 + // 调用,并断言异常
  95 + assertServiceException(() -> smsCodeService.sendSmsCode(reqDTO),
  96 + SMS_CODE_SEND_TOO_FAST);
  97 + }
  98 +
  99 + @Test
  100 + public void sendSmsCode_exceedDay() {
  101 + // mock 数据
  102 + SmsCodeDO smsCodeDO = randomPojo(SmsCodeDO.class,
  103 + o -> o.setMobile("15601691300").setTodayIndex(10).setCreateTime(LocalDateTime.now()));
  104 + smsCodeMapper.insert(smsCodeDO);
  105 + // 准备参数
  106 + SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
  107 + o.setMobile("15601691300");
  108 + o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene());
  109 + });
  110 + // mock 方法
  111 + SqlConstants.init(DbType.MYSQL);
  112 + when(smsCodeProperties.getSendFrequency()).thenReturn(Duration.ofMillis(0));
  113 +
  114 + // 调用,并断言异常
  115 + assertServiceException(() -> smsCodeService.sendSmsCode(reqDTO),
  116 + SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY);
  117 + }
  118 +
  119 + @Test
  120 + public void testUseSmsCode_success() {
  121 + // 准备参数
  122 + SmsCodeUseReqDTO reqDTO = randomPojo(SmsCodeUseReqDTO.class, o -> {
  123 + o.setMobile("15601691300");
  124 + o.setScene(randomEle(SmsSceneEnum.values()).getScene());
  125 + });
  126 + // mock 数据
  127 + SqlConstants.init(DbType.MYSQL);
  128 + smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> {
  129 + o.setMobile(reqDTO.getMobile()).setScene(reqDTO.getScene())
  130 + .setCode(reqDTO.getCode()).setUsed(false);
  131 + }));
  132 +
  133 + // 调用
  134 + smsCodeService.useSmsCode(reqDTO);
  135 + // 断言
  136 + SmsCodeDO smsCodeDO = smsCodeMapper.selectOne(null);
  137 + assertTrue(smsCodeDO.getUsed());
  138 + assertNotNull(smsCodeDO.getUsedTime());
  139 + assertEquals(reqDTO.getUsedIp(), smsCodeDO.getUsedIp());
  140 + }
  141 +
  142 + @Test
  143 + public void validateSmsCode_success() {
  144 + // 准备参数
  145 + SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
  146 + o.setMobile("15601691300");
  147 + o.setScene(randomEle(SmsSceneEnum.values()).getScene());
  148 + });
  149 + // mock 数据
  150 + SqlConstants.init(DbType.MYSQL);
  151 + smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile())
  152 + .setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(false)));
  153 +
  154 + // 调用
  155 + smsCodeService.validateSmsCode(reqDTO);
  156 + }
  157 +
  158 + @Test
  159 + public void validateSmsCode_notFound() {
  160 + // 准备参数
  161 + SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
  162 + o.setMobile("15601691300");
  163 + o.setScene(randomEle(SmsSceneEnum.values()).getScene());
  164 + });
  165 + // mock 数据
  166 + SqlConstants.init(DbType.MYSQL);
  167 +
  168 + // 调用,并断言异常
  169 + assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO),
  170 + SMS_CODE_NOT_FOUND);
  171 + }
  172 +
  173 + @Test
  174 + public void validateSmsCode_expired() {
  175 + // 准备参数
  176 + SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
  177 + o.setMobile("15601691300");
  178 + o.setScene(randomEle(SmsSceneEnum.values()).getScene());
  179 + });
  180 + // mock 数据
  181 + SqlConstants.init(DbType.MYSQL);
  182 + smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile())
  183 + .setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(false)
  184 + .setCreateTime(LocalDateTime.now().minusMinutes(6))));
  185 +
  186 + // 调用,并断言异常
  187 + assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO),
  188 + SMS_CODE_EXPIRED);
  189 + }
  190 +
  191 + @Test
  192 + public void validateSmsCode_used() {
  193 + // 准备参数
  194 + SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
  195 + o.setMobile("15601691300");
  196 + o.setScene(randomEle(SmsSceneEnum.values()).getScene());
  197 + });
  198 + // mock 数据
  199 + SqlConstants.init(DbType.MYSQL);
  200 + smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile())
  201 + .setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(true)
  202 + .setCreateTime(LocalDateTime.now())));
  203 +
  204 + // 调用,并断言异常
  205 + assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO),
  206 + SMS_CODE_USED);
  207 + }
  208 +
  209 +}
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsLogServiceTest.java renamed to yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsLogServiceImplTest.java
@@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; @@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
34 import static org.junit.jupiter.api.Assertions.assertNotNull; 34 import static org.junit.jupiter.api.Assertions.assertNotNull;
35 35
36 @Import(SmsLogServiceImpl.class) 36 @Import(SmsLogServiceImpl.class)
37 -public class SmsLogServiceTest extends BaseDbUnitTest { 37 +public class SmsLogServiceImplTest extends BaseDbUnitTest {
38 38
39 @Resource 39 @Resource
40 private SmsLogServiceImpl smsLogService; 40 private SmsLogServiceImpl smsLogService;
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceTest.java renamed to yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImplTest.java
@@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; @@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
34 import static org.mockito.ArgumentMatchers.eq; 34 import static org.mockito.ArgumentMatchers.eq;
35 import static org.mockito.Mockito.*; 35 import static org.mockito.Mockito.*;
36 36
37 -public class SmsSendServiceTest extends BaseMockitoUnitTest { 37 +public class SmsSendServiceImplTest extends BaseMockitoUnitTest {
38 38
39 @InjectMocks 39 @InjectMocks
40 private SmsSendServiceImpl smsService; 40 private SmsSendServiceImpl smsService;
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceTest.java renamed to yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImplTest.java
@@ -30,9 +30,7 @@ import java.util.List; @@ -30,9 +30,7 @@ import java.util.List;
30 import java.util.Map; 30 import java.util.Map;
31 import java.util.function.Consumer; 31 import java.util.function.Consumer;
32 32
33 -import static cn.hutool.core.bean.BeanUtil.getFieldValue;  
34 import static cn.hutool.core.util.RandomUtil.randomEle; 33 import static cn.hutool.core.util.RandomUtil.randomEle;
35 -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;  
36 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; 34 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
37 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; 35 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
38 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; 36 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
@@ -43,7 +41,7 @@ import static org.mockito.ArgumentMatchers.eq; @@ -43,7 +41,7 @@ import static org.mockito.ArgumentMatchers.eq;
43 import static org.mockito.Mockito.*; 41 import static org.mockito.Mockito.*;
44 42
45 @Import(SmsTemplateServiceImpl.class) 43 @Import(SmsTemplateServiceImpl.class)
46 -public class SmsTemplateServiceTest extends BaseDbUnitTest { 44 +public class SmsTemplateServiceImplTest extends BaseDbUnitTest {
47 45
48 @Resource 46 @Resource
49 private SmsTemplateServiceImpl smsTemplateService; 47 private SmsTemplateServiceImpl smsTemplateService;
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql
@@ -14,6 +14,7 @@ DELETE FROM &quot;system_users&quot;; @@ -14,6 +14,7 @@ DELETE FROM &quot;system_users&quot;;
14 DELETE FROM "system_sms_channel"; 14 DELETE FROM "system_sms_channel";
15 DELETE FROM "system_sms_template"; 15 DELETE FROM "system_sms_template";
16 DELETE FROM "system_sms_log"; 16 DELETE FROM "system_sms_log";
  17 +DELETE FROM "system_sms_code";
17 DELETE FROM "system_error_code"; 18 DELETE FROM "system_error_code";
18 DELETE FROM "system_social_user"; 19 DELETE FROM "system_social_user";
19 DELETE FROM "system_social_user_bind"; 20 DELETE FROM "system_social_user_bind";
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql
@@ -377,6 +377,24 @@ CREATE TABLE IF NOT EXISTS &quot;system_sms_log&quot; ( @@ -377,6 +377,24 @@ CREATE TABLE IF NOT EXISTS &quot;system_sms_log&quot; (
377 PRIMARY KEY ("id") 377 PRIMARY KEY ("id")
378 ) COMMENT '短信日志'; 378 ) COMMENT '短信日志';
379 379
  380 +CREATE TABLE IF NOT EXISTS "system_sms_code" (
  381 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  382 + "mobile" varchar(11) NOT NULL,
  383 + "code" varchar(11) NOT NULL,
  384 + "scene" bigint NOT NULL,
  385 + "create_ip" varchar NOT NULL,
  386 + "today_index" int NOT NULL,
  387 + "used" bit NOT NULL DEFAULT FALSE,
  388 + "used_time" timestamp DEFAULT NULL,
  389 + "used_ip" varchar NULL,
  390 + "creator" varchar(64) DEFAULT '',
  391 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  392 + "updater" varchar(64) DEFAULT '',
  393 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  394 + "deleted" bit NOT NULL DEFAULT FALSE,
  395 + PRIMARY KEY ("id")
  396 +) COMMENT '短信日志';
  397 +
380 CREATE TABLE IF NOT EXISTS "system_error_code" ( 398 CREATE TABLE IF NOT EXISTS "system_error_code" (
381 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, 399 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
382 "type" tinyint NOT NULL DEFAULT '0', 400 "type" tinyint NOT NULL DEFAULT '0',