13404089107
2026-04-20 f4b6843a1b3990453d2aef6d87b5ac30723c5870
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package com.tcm.training.admin.app.auth.service;
 
import com.tcm.training.admin.app.auth.config.AppSmsAuthProperties;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
 
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
 
/**
 * APP 短信验证码场景化调试配置测试。
 */
@ExtendWith(MockitoExtension.class)
class AppSmsCodeServiceTest {
 
    @Mock
    private StringRedisTemplate stringRedisTemplate;
 
    @Mock
    private ValueOperations<String, String> valueOperations;
 
    @Mock
    private AppSmsSender appSmsSender;
 
    private AppSmsAuthProperties appSmsAuthProperties;
 
    private AppSmsCodeService appSmsCodeService;
 
    /**
     * 每个用例前重新构造短信验证码服务。
     */
    @BeforeEach
    void setUp() {
        appSmsAuthProperties = new AppSmsAuthProperties();
        appSmsAuthProperties.getLogin().setEnabled(true);
        appSmsAuthProperties.getLogin().setCode("666666");
        appSmsAuthProperties.getRegister().setEnabled(false);
        appSmsAuthProperties.getRegister().setCode("");
        appSmsAuthProperties.getPasswordReset().setEnabled(false);
        appSmsAuthProperties.getPasswordReset().setCode("");
        appSmsAuthProperties.getPhoneChange().setEnabled(false);
        appSmsAuthProperties.getPhoneChange().setCode("");
 
        appSmsCodeService = new AppSmsCodeService(
                stringRedisTemplate,
                appSmsSender,
                appSmsAuthProperties
        );
    }
 
    /**
     * 仅开启登录调试验证码时,666666 应允许短信登录直接通过。
     */
    @Test
    void validateLoginCodeShouldAllowConfiguredDebugCode() {
        assertDoesNotThrow(() -> appSmsCodeService.validateLoginCode("13800138000", "666666"));
        verify(stringRedisTemplate, never()).opsForValue();
    }
 
    /**
     * 未开启注册调试验证码时,666666 不应绕过真实验证码校验。
     */
    @Test
    void validateRegisterCodeShouldRejectDebugCodeWhenSceneDisabled() {
        when(stringRedisTemplate.opsForValue()).thenReturn(valueOperations);
        when(valueOperations.get(anyString())).thenReturn(null);
 
        IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
                () -> appSmsCodeService.validateRegisterCode("13800138000", "666666"));
 
        assertEquals("验证码已失效,请重新获取", exception.getMessage());
    }
 
    /**
     * 短信发送成功后才应写入验证码缓存。
     */
    @Test
    void createLoginCodeShouldCacheCodeAfterSendSucceeds() {
        when(stringRedisTemplate.opsForValue()).thenReturn(valueOperations);
 
        appSmsCodeService.createLoginCode("13800138000");
 
        verify(appSmsSender).sendLoginCode(eq("13800138000"), anyString());
        verify(valueOperations).set(anyString(), anyString(), anyLong(), eq(java.util.concurrent.TimeUnit.SECONDS));
    }
 
    /**
     * 短信发送失败时不应写入验证码缓存。
     */
    @Test
    void createLoginCodeShouldNotCacheCodeWhenSendFails() {
        org.mockito.Mockito.doThrow(new IllegalStateException("短信发送失败,请稍后重试"))
                .when(appSmsSender).sendLoginCode(eq("13800138000"), anyString());
 
        IllegalStateException exception = assertThrows(IllegalStateException.class,
                () -> appSmsCodeService.createLoginCode("13800138000"));
 
        assertEquals("短信发送失败,请稍后重试", exception.getMessage());
        verify(valueOperations, never()).set(anyString(), anyString(), anyLong(), eq(java.util.concurrent.TimeUnit.SECONDS));
    }
}