“mitao”
2026-05-12 5b5553bb13ae1dbd31e0fb7edfadac76c0642a8c
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
package com.tcm.training.admin.utils;
 
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tcm.training.admin.app.auth.config.AppAliyunSmsProperties;
import org.junit.jupiter.api.Test;
 
import java.util.Collections;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
 
/**
 * 阿里云短信工具异常处理测试。
 */
class MsgUtilsTest {
 
    /**
     * 普通异常 message 为空时,应保留统一业务异常而不是被阿里云类型断言覆盖。
     */
    @Test
    void sendMsgShouldHandleExceptionWithNullMessage() throws Exception {
        MsgUtils msgUtils = new TestMsgUtils(new FailingSmsClient(new RuntimeException((String) null)));
 
        IllegalStateException exception = assertThrows(IllegalStateException.class,
                () -> msgUtils.sendMsg("13800138000", Collections.singletonMap("code", "123456"), "SMS_TEST", "海诊通"));
 
        assertEquals("短信发送失败,请稍后重试", exception.getMessage());
    }
 
    /**
     * 阿里云 TeaException message 为空时,也不能二次抛出 TeaUtilException。
     */
    @Test
    void sendMsgShouldHandleTeaExceptionWithNullMessage() throws Exception {
        TeaException teaException = new TeaException((String) null, new RuntimeException("sdk failed"));
        MsgUtils msgUtils = new TestMsgUtils(new FailingSmsClient(teaException));
 
        IllegalStateException exception = assertThrows(IllegalStateException.class,
                () -> msgUtils.sendMsg("13800138000", Collections.singletonMap("code", "123456"), "SMS_TEST", "海诊通"));
 
        assertEquals("短信发送失败,请稍后重试", exception.getMessage());
    }
 
    /**
     * 可注入短信客户端的测试工具类。
     */
    private static class TestMsgUtils extends MsgUtils {
 
        private final com.aliyun.dysmsapi20170525.Client client;
 
        private TestMsgUtils(com.aliyun.dysmsapi20170525.Client client) {
            super(new AppAliyunSmsProperties(), new ObjectMapper());
            this.client = client;
        }
 
        /**
         * 返回测试短信客户端。
         */
        @Override
        protected com.aliyun.dysmsapi20170525.Client createSmsClient() {
            return client;
        }
    }
 
    /**
     * 固定抛异常的阿里云短信客户端。
     */
    private static class FailingSmsClient extends com.aliyun.dysmsapi20170525.Client {
 
        private final Exception exception;
 
        private FailingSmsClient(Exception exception) throws Exception {
            super(new Config().setAccessKeyId("test-ak").setAccessKeySecret("test-sk").setEndpoint("dysmsapi.aliyuncs.com"));
            this.exception = exception;
        }
 
        /**
         * 模拟阿里云发送接口异常。
         */
        @Override
        public SendSmsResponse sendSmsWithOptions(SendSmsRequest request, RuntimeOptions runtime) throws Exception {
            throw exception;
        }
    }
}