Commit a432b303e6690164466fc2ae63667dea302b592b

Authored by YunaiV
1 parent 71d2f741

完成 AliyunSmsClient 的单元测试

完成 YunpianSmsClient 的单元测试
src/main/java/cn/iocoder/dashboard/framework/sms/core/client/impl/aliyun/AliyunSmsClient.java
... ... @@ -24,6 +24,7 @@ import com.aliyuncs.profile.DefaultProfile;
24 24 import com.aliyuncs.profile.IClientProfile;
25 25 import com.fasterxml.jackson.annotation.JsonFormat;
26 26 import com.fasterxml.jackson.annotation.JsonProperty;
  27 +import com.google.common.annotations.VisibleForTesting;
27 28 import lombok.Data;
28 29 import lombok.extern.slf4j.Slf4j;
29 30  
... ... @@ -53,7 +54,7 @@ public class AliyunSmsClient extends AbstractSmsClient {
53 54 /**
54 55 * 阿里云客户端
55 56 */
56   - private volatile IAcsClient acsClient;
  57 + private volatile IAcsClient client;
57 58  
58 59 public AliyunSmsClient(SmsChannelProperties properties) {
59 60 super(properties, new AliyunSmsCodeMapping());
... ... @@ -64,7 +65,7 @@ public class AliyunSmsClient extends AbstractSmsClient {
64 65 @Override
65 66 protected void doInit() {
66 67 IClientProfile profile = DefaultProfile.getProfile(ENDPOINT, properties.getApiKey(), properties.getApiSecret());
67   - acsClient = new DefaultAcsClient(profile);
  68 + client = new DefaultAcsClient(profile);
68 69 }
69 70  
70 71 @Override
... ... @@ -81,13 +82,6 @@ public class AliyunSmsClient extends AbstractSmsClient {
81 82 return invoke(request, response -> new SmsSendRespDTO().setSerialNo(response.getBizId()));
82 83 }
83 84  
84   - private static String formatResultMsg(ClientException ex) {
85   - if (StrUtil.isEmpty(ex.getErrorDescription())) {
86   - return ex.getMessage();
87   - }
88   - return ex.getErrMsg() + " => " + ex.getErrorDescription();
89   - }
90   -
91 85 @Override
92 86 protected List<SmsReceiveRespDTO> doParseSmsReceiveStatus(String text) throws Throwable {
93 87 List<SmsReceiveStatus> statuses = JsonUtils.parseArray(text, SmsReceiveStatus.class);
... ... @@ -115,7 +109,8 @@ public class AliyunSmsClient extends AbstractSmsClient {
115 109 });
116 110 }
117 111  
118   - private Integer convertSmsTemplateAuditStatus(Integer templateStatus) {
  112 + @VisibleForTesting
  113 + Integer convertSmsTemplateAuditStatus(Integer templateStatus) {
119 114 switch (templateStatus) {
120 115 case 0: return SmsTemplateAuditStatusEnum.CHECKING.getStatus();
121 116 case 1: return SmsTemplateAuditStatusEnum.SUCCESS.getStatus();
... ... @@ -124,10 +119,11 @@ public class AliyunSmsClient extends AbstractSmsClient {
124 119 }
125 120 }
126 121  
127   - private <T extends AcsResponse, R> SmsCommonResult<R> invoke(AcsRequest<T> request, Function<T, R> responseConsumer) {
  122 + @VisibleForTesting
  123 + <T extends AcsResponse, R> SmsCommonResult<R> invoke(AcsRequest<T> request, Function<T, R> responseConsumer) {
128 124 try {
129 125 // 执行发送. 由于阿里云 sms 短信没有统一的 Response,但是有统一的 code、message、requestId 属性,所以只好反射
130   - T sendResult = acsClient.getAcsResponse(request);
  126 + T sendResult = client.getAcsResponse(request);
131 127 String code = (String) ReflectUtil.getFieldValue(sendResult, "code");
132 128 String message = (String) ReflectUtil.getFieldValue(sendResult, "message");
133 129 String requestId = (String) ReflectUtil.getFieldValue(sendResult, "requestId");
... ... @@ -143,6 +139,13 @@ public class AliyunSmsClient extends AbstractSmsClient {
143 139 }
144 140 }
145 141  
  142 + private static String formatResultMsg(ClientException ex) {
  143 + if (StrUtil.isEmpty(ex.getErrorDescription())) {
  144 + return ex.getErrMsg();
  145 + }
  146 + return ex.getErrMsg() + " => " + ex.getErrorDescription();
  147 + }
  148 +
146 149 /**
147 150 * 短信接收状态
148 151 *
... ...
src/main/java/cn/iocoder/dashboard/framework/sms/core/client/impl/yunpian/YunpianSmsClient.java
... ... @@ -15,6 +15,7 @@ import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
15 15 import cn.iocoder.dashboard.util.json.JsonUtils;
16 16 import com.fasterxml.jackson.annotation.JsonFormat;
17 17 import com.fasterxml.jackson.annotation.JsonProperty;
  18 +import com.google.common.annotations.VisibleForTesting;
18 19 import com.yunpian.sdk.YunpianClient;
19 20 import com.yunpian.sdk.constant.YunpianConstant;
20 21 import com.yunpian.sdk.model.Result;
... ... @@ -113,7 +114,8 @@ public class YunpianSmsClient extends AbstractSmsClient {
113 114 });
114 115 }
115 116  
116   - private Integer convertSmsTemplateAuditStatus(String checkStatus) {
  117 + @VisibleForTesting
  118 + Integer convertSmsTemplateAuditStatus(String checkStatus) {
117 119 switch (checkStatus) {
118 120 case "CHECKING": return SmsTemplateAuditStatusEnum.CHECKING.getStatus();
119 121 case "SUCCESS": return SmsTemplateAuditStatusEnum.SUCCESS.getStatus();
... ... @@ -122,7 +124,8 @@ public class YunpianSmsClient extends AbstractSmsClient {
122 124 }
123 125 }
124 126  
125   - private <T, R> SmsCommonResult<R> invoke(Supplier<Result<T>> requestConsumer, Function<T, R> responseConsumer) throws Throwable {
  127 + @VisibleForTesting
  128 + <T, R> SmsCommonResult<R> invoke(Supplier<Result<T>> requestConsumer, Function<T, R> responseConsumer) throws Throwable {
126 129 // 执行请求
127 130 Result<T> result = requestConsumer.get();
128 131 if (result.getThrowable() != null) {
... ...
src/test/java/cn/iocoder/dashboard/framework/sms/core/client/impl/aliyun/AliyunSmsClientTest.java
1 1 package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun;
2 2  
  3 +import cn.hutool.core.util.ReflectUtil;
  4 +import cn.iocoder.dashboard.BaseMockitoUnitTest;
  5 +import cn.iocoder.dashboard.common.core.KeyValue;
  6 +import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
  7 +import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
3 8 import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsReceiveRespDTO;
  9 +import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
  10 +import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsTemplateRespDTO;
  11 +import cn.iocoder.dashboard.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
  12 +import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
  13 +import cn.iocoder.dashboard.util.collection.MapUtils;
4 14 import cn.iocoder.dashboard.util.date.DateUtils;
  15 +import com.aliyuncs.AcsRequest;
  16 +import com.aliyuncs.IAcsClient;
  17 +import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateRequest;
  18 +import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateResponse;
  19 +import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
  20 +import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
  21 +import com.aliyuncs.exceptions.ClientException;
  22 +import com.google.common.collect.Lists;
5 23 import org.junit.jupiter.api.Test;
  24 +import org.mockito.ArgumentMatcher;
6 25 import org.mockito.InjectMocks;
  26 +import org.mockito.Mock;
7 27  
8 28 import java.util.List;
  29 +import java.util.function.Function;
9 30  
10   -import static org.junit.jupiter.api.Assertions.assertEquals;
11   -import static org.junit.jupiter.api.Assertions.assertTrue;
  31 +import static cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants.SMS_API_PARAM_ERROR;
  32 +import static cn.iocoder.dashboard.util.RandomUtils.*;
  33 +import static cn.iocoder.dashboard.util.json.JsonUtils.toJsonString;
  34 +import static org.junit.jupiter.api.Assertions.*;
  35 +import static org.mockito.ArgumentMatchers.any;
  36 +import static org.mockito.ArgumentMatchers.argThat;
  37 +import static org.mockito.Mockito.when;
12 38  
13 39 /**
14 40 * {@link AliyunSmsClient} 的单元测试
  41 + *
  42 + * @author 芋道源码
15 43 */
16   -public class AliyunSmsClientTest {
  44 +public class AliyunSmsClientTest extends BaseMockitoUnitTest {
  45 +
  46 + private final SmsChannelProperties properties = new SmsChannelProperties()
  47 + .setApiKey(randomString()) // 随机一个 apiKey,避免构建报错
  48 + .setApiSecret(randomString()) // 随机一个 apiSecret,避免构建报错
  49 + .setSignature("芋道源码");
17 50  
18 51 @InjectMocks
19   - private final AliyunSmsClient smsClient = new AliyunSmsClient(null);
  52 + private final AliyunSmsClient smsClient = new AliyunSmsClient(properties);
  53 +
  54 + @Mock
  55 + private IAcsClient client;
20 56  
21 57 @Test
22   - void doInit() {
  58 + public void testDoInit() {
  59 + // 准备参数
  60 + // mock 方法
  61 +
  62 + // 调用
  63 + smsClient.doInit();
  64 + // 断言
  65 + assertNotSame(client, ReflectUtil.getFieldValue(smsClient, "acsClient"));
23 66 }
24 67  
25 68 @Test
26   - void doSendSms() {
  69 + @SuppressWarnings("unchecked")
  70 + public void testDoSendSms() throws ClientException {
  71 + // 准备参数
  72 + Long sendLogId = randomLongId();
  73 + String mobile = randomString();
  74 + String apiTemplateId = randomString();
  75 + List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
  76 + new KeyValue<>("code", 1234), new KeyValue<>("op", "login"));
  77 + // mock 方法
  78 + SendSmsResponse response = randomPojo(SendSmsResponse.class, o -> o.setCode("OK"));
  79 + when(client.getAcsResponse(argThat((ArgumentMatcher<SendSmsRequest>) acsRequest -> {
  80 + assertEquals(mobile, acsRequest.getPhoneNumbers());
  81 + assertEquals(properties.getSignature(), acsRequest.getSignName());
  82 + assertEquals(apiTemplateId, acsRequest.getTemplateCode());
  83 + assertEquals(toJsonString(MapUtils.convertMap(templateParams)), acsRequest.getTemplateParam());
  84 + assertEquals(sendLogId.toString(), acsRequest.getOutId());
  85 + return true;
  86 + }))).thenReturn(response);
  87 +
  88 + // 调用
  89 + SmsCommonResult<SmsSendRespDTO> result = smsClient.doSendSms(sendLogId, mobile,
  90 + apiTemplateId, templateParams);
  91 + // 断言
  92 + assertEquals(response.getCode(), result.getApiCode());
  93 + assertEquals(response.getMessage(), result.getApiMsg());
  94 + assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
  95 + assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
  96 + assertEquals(response.getRequestId(), result.getApiRequestId());
  97 + // 断言结果
  98 + assertEquals(response.getBizId(), result.getData().getSerialNo());
27 99 }
28 100  
29 101 @Test
... ... @@ -57,4 +129,96 @@ public class AliyunSmsClientTest {
57 129 assertEquals(67890L, statuses.get(0).getLogId());
58 130 }
59 131  
  132 + @Test
  133 + public void testDoGetSmsTemplate() throws ClientException {
  134 + // 准备参数
  135 + String apiTemplateId = randomString();
  136 + // mock 方法
  137 + QuerySmsTemplateResponse response = randomPojo(QuerySmsTemplateResponse.class, o -> {
  138 + o.setCode("OK");
  139 + o.setTemplateStatus(1); // 设置模板通过
  140 + });
  141 + when(client.getAcsResponse(argThat((ArgumentMatcher<QuerySmsTemplateRequest>) acsRequest -> {
  142 + assertEquals(apiTemplateId, acsRequest.getTemplateCode());
  143 + return true;
  144 + }))).thenReturn(response);
  145 +
  146 + // 调用
  147 + SmsCommonResult<SmsTemplateRespDTO> result = smsClient.doGetSmsTemplate(apiTemplateId);
  148 + // 断言
  149 + assertEquals(response.getCode(), result.getApiCode());
  150 + assertEquals(response.getMessage(), result.getApiMsg());
  151 + assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
  152 + assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
  153 + assertEquals(response.getRequestId(), result.getApiRequestId());
  154 + // 断言结果
  155 + assertEquals(response.getTemplateCode(), result.getData().getId());
  156 + assertEquals(response.getTemplateContent(), result.getData().getContent());
  157 + assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(), result.getData().getAuditStatus());
  158 + assertEquals(response.getReason(), result.getData().getAuditReason());
  159 + }
  160 +
  161 + @Test
  162 + public void testConvertSmsTemplateAuditStatus() {
  163 + assertEquals(SmsTemplateAuditStatusEnum.CHECKING.getStatus(),
  164 + smsClient.convertSmsTemplateAuditStatus(0));
  165 + assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(),
  166 + smsClient.convertSmsTemplateAuditStatus(1));
  167 + assertEquals(SmsTemplateAuditStatusEnum.FAIL.getStatus(),
  168 + smsClient.convertSmsTemplateAuditStatus(2));
  169 + assertThrows(IllegalArgumentException.class, () -> smsClient.convertSmsTemplateAuditStatus(3),
  170 + "未知审核状态(3)");
  171 + }
  172 +
  173 + @Test
  174 + @SuppressWarnings("unchecked")
  175 + public void testInvoke_throwable() throws ClientException {
  176 + // 准备参数
  177 + QuerySmsTemplateRequest request = new QuerySmsTemplateRequest();
  178 + // mock 方法
  179 + ClientException ex = new ClientException("isv.INVALID_PARAMETERS", "参数不正确", randomString());
  180 + when(client.getAcsResponse(any(AcsRequest.class))).thenThrow(ex);
  181 +
  182 + // 调用,并断言异常
  183 + SmsCommonResult<?> result = smsClient.invoke(request,null);
  184 + // 断言
  185 + assertEquals(ex.getErrCode(), result.getApiCode());
  186 + assertEquals(ex.getErrMsg(), result.getApiMsg());
  187 + assertEquals(SMS_API_PARAM_ERROR.getCode(), result.getCode());
  188 + assertEquals(SMS_API_PARAM_ERROR.getMsg(), result.getMsg());
  189 + assertEquals(ex.getRequestId(), result.getApiRequestId());
  190 + }
  191 +
  192 + @Test
  193 + public void testInvoke_success() throws ClientException {
  194 + // 准备参数
  195 + QuerySmsTemplateRequest request = new QuerySmsTemplateRequest();
  196 + Function<QuerySmsTemplateResponse, SmsTemplateRespDTO> responseConsumer = response -> {
  197 + SmsTemplateRespDTO data = new SmsTemplateRespDTO();
  198 + data.setId(response.getTemplateCode()).setContent(response.getTemplateContent());
  199 + data.setAuditStatus(SmsTemplateAuditStatusEnum.SUCCESS.getStatus()).setAuditReason(response.getReason());
  200 + return data;
  201 + };
  202 + // mock 方法
  203 + QuerySmsTemplateResponse response = randomPojo(QuerySmsTemplateResponse.class, o -> {
  204 + o.setCode("OK");
  205 + o.setTemplateStatus(1); // 设置模板通过
  206 + });
  207 + when(client.getAcsResponse(any(AcsRequest.class))).thenReturn(response);
  208 +
  209 + // 调用
  210 + SmsCommonResult<SmsTemplateRespDTO> result = smsClient.invoke(request, responseConsumer);
  211 + // 断言
  212 + assertEquals(response.getCode(), result.getApiCode());
  213 + assertEquals(response.getMessage(), result.getApiMsg());
  214 + assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
  215 + assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
  216 + assertEquals(response.getRequestId(), result.getApiRequestId());
  217 + // 断言结果
  218 + assertEquals(response.getTemplateCode(), result.getData().getId());
  219 + assertEquals(response.getTemplateContent(), result.getData().getContent());
  220 + assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(), result.getData().getAuditStatus());
  221 + assertEquals(response.getReason(), result.getData().getAuditReason());
  222 + }
  223 +
60 224 }
... ...
src/test/java/cn/iocoder/dashboard/framework/sms/core/client/impl/yunpian/YunpianSmsClientTest.java
1 1 package cn.iocoder.dashboard.framework.sms.core.client.impl.yunpian;
2 2  
  3 +import cn.hutool.core.util.ReflectUtil;
  4 +import cn.iocoder.dashboard.BaseMockitoUnitTest;
  5 +import cn.iocoder.dashboard.common.core.KeyValue;
  6 +import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
  7 +import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
3 8 import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsReceiveRespDTO;
  9 +import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
  10 +import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsTemplateRespDTO;
  11 +import cn.iocoder.dashboard.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
  12 +import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
4 13 import cn.iocoder.dashboard.util.date.DateUtils;
  14 +import com.google.common.collect.Lists;
  15 +import com.yunpian.sdk.YunpianClient;
  16 +import com.yunpian.sdk.api.SmsApi;
  17 +import com.yunpian.sdk.api.TplApi;
  18 +import com.yunpian.sdk.constant.YunpianConstant;
  19 +import com.yunpian.sdk.model.Result;
  20 +import com.yunpian.sdk.model.SmsSingleSend;
  21 +import com.yunpian.sdk.model.Template;
5 22 import org.junit.jupiter.api.Test;
6 23 import org.mockito.InjectMocks;
  24 +import org.mockito.Mock;
7 25  
  26 +import java.util.HashMap;
8 27 import java.util.List;
  28 +import java.util.Map;
  29 +import java.util.function.Function;
  30 +import java.util.function.Supplier;
9 31  
  32 +import static cn.iocoder.dashboard.util.RandomUtils.*;
  33 +import static com.yunpian.sdk.constant.Code.OK;
10 34 import static org.junit.jupiter.api.Assertions.*;
  35 +import static org.mockito.Mockito.*;
11 36  
12 37 /**
13 38 * 对 {@link YunpianSmsClient} 的单元测试
  39 + *
  40 + * @author 芋道源码
14 41 */
15   -public class YunpianSmsClientTest {
  42 +public class YunpianSmsClientTest extends BaseMockitoUnitTest {
  43 +
  44 + private final SmsChannelProperties properties = new SmsChannelProperties()
  45 + .setApiKey(randomString()); // 随机一个 apiKey,避免构建报错
16 46  
17 47 @InjectMocks
18   - private final YunpianSmsClient smsClient = new YunpianSmsClient(null);
  48 + private final YunpianSmsClient smsClient = new YunpianSmsClient(properties);
  49 +
  50 + @Mock
  51 + private YunpianClient client;
19 52  
20 53 @Test
21   - void doInit() {
  54 + public void testDoInit() {
  55 + // 准备参数
  56 + // mock 方法
  57 +
  58 + // 调用
  59 + smsClient.doInit();
  60 + // 断言
  61 + assertNotEquals(client, ReflectUtil.getFieldValue(smsClient, "client"));
  62 + verify(client, times(1)).close();
22 63 }
23 64  
24 65 @Test
25   - void doSendSms() {
  66 + @SuppressWarnings("unchecked")
  67 + public void testDoSendSms() throws Throwable {
  68 + // 准备参数
  69 + Long sendLogId = randomLongId();
  70 + String mobile = randomString();
  71 + String apiTemplateId = randomString();
  72 + List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
  73 + new KeyValue<>("code", 1234), new KeyValue<>("op", "login"));
  74 + // mock sms 方法
  75 + SmsApi smsApi = mock(SmsApi.class);
  76 + when(client.sms()).thenReturn(smsApi);
  77 + // mock tpl_single_send 方法
  78 + Map<String, String> request = new HashMap<>();
  79 + request.put(YunpianConstant.MOBILE, mobile);
  80 + request.put(YunpianConstant.TPL_ID, apiTemplateId);
  81 + request.put(YunpianConstant.TPL_VALUE, "#code#=1234&#op#=login");
  82 + request.put(YunpianConstant.UID, String.valueOf(sendLogId));
  83 + request.put(YunpianConstant.CALLBACK_URL, properties.getCallbackUrl());
  84 + Result<SmsSingleSend> responseResult = randomPojo(Result.class, SmsSingleSend.class,
  85 + o -> o.setCode(OK)); // API 发送成功的 code
  86 + when(smsApi.tpl_single_send(eq(request))).thenReturn(responseResult);
  87 +
  88 + // 调用
  89 + SmsCommonResult<SmsSendRespDTO> result = smsClient.doSendSms(sendLogId, mobile,
  90 + apiTemplateId, templateParams);
  91 + // 断言
  92 + assertEquals(String.valueOf(responseResult.getCode()), result.getApiCode());
  93 + assertEquals(responseResult.getMsg() + " => " + responseResult.getDetail(), result.getApiMsg());
  94 + assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
  95 + assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
  96 + assertNull(result.getApiRequestId());
  97 + // 断言结果
  98 + assertEquals(String.valueOf(responseResult.getData().getSid()), result.getData().getSerialNo());
26 99 }
27 100  
28 101 @Test
29   - void testDoParseSmsReceiveStatus() throws Throwable {
  102 + public void testDoParseSmsReceiveStatus() throws Throwable {
30 103 // 准备参数
31 104 String text = "[{\"sid\":9527,\"uid\":1024,\"user_receive_time\":\"2014-03-17 22:55:21\",\"error_msg\":\"\",\"mobile\":\"15205201314\",\"report_status\":\"SUCCESS\"}]";
32 105 // mock 方法
... ... @@ -47,4 +120,83 @@ public class YunpianSmsClientTest {
47 120 assertEquals(1024L, statuses.get(0).getLogId());
48 121 }
49 122  
  123 + @Test
  124 + @SuppressWarnings("unchecked")
  125 + public void testDoGetSmsTemplate() throws Throwable {
  126 + // 准备参数
  127 + String apiTemplateId = randomString();
  128 + // mock tpl 方法
  129 + TplApi tplApi = mock(TplApi.class);
  130 + when(client.tpl()).thenReturn(tplApi);
  131 + // mock get 方法
  132 + Map<String, String> request = new HashMap<>();
  133 + request.put(YunpianConstant.APIKEY, properties.getApiKey());
  134 + request.put(YunpianConstant.TPL_ID, apiTemplateId);
  135 + Result<List<Template>> responseResult = randomPojo(Result.class, List.class, o -> {
  136 + o.setCode(OK); // API 发送成功的 code
  137 + o.setData(randomPojoList(Template.class, t -> t.setCheck_status("SUCCESS")));
  138 + });
  139 + when(tplApi.get(eq(request))).thenReturn(responseResult);
  140 +
  141 + // 调用
  142 + SmsCommonResult<SmsTemplateRespDTO> result = smsClient.doGetSmsTemplate(apiTemplateId);
  143 + // 断言
  144 + assertEquals(String.valueOf(responseResult.getCode()), result.getApiCode());
  145 + assertEquals(responseResult.getMsg() + " => " + responseResult.getDetail(), result.getApiMsg());
  146 + assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
  147 + assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
  148 + assertNull(result.getApiRequestId());
  149 + // 断言结果
  150 + Template template = responseResult.getData().get(0);
  151 + assertEquals(template.getTpl_id().toString(), result.getData().getId());
  152 + assertEquals(template.getTpl_content(), result.getData().getContent());
  153 + assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(), result.getData().getAuditStatus());
  154 + assertEquals(template.getReason(), result.getData().getAuditReason());
  155 + }
  156 +
  157 + @Test
  158 + public void testConvertSmsTemplateAuditStatus() {
  159 + assertEquals(SmsTemplateAuditStatusEnum.CHECKING.getStatus(),
  160 + smsClient.convertSmsTemplateAuditStatus("CHECKING"));
  161 + assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(),
  162 + smsClient.convertSmsTemplateAuditStatus("SUCCESS"));
  163 + assertEquals(SmsTemplateAuditStatusEnum.FAIL.getStatus(),
  164 + smsClient.convertSmsTemplateAuditStatus("FAIL"));
  165 + assertThrows(IllegalArgumentException.class, () -> smsClient.convertSmsTemplateAuditStatus("test"),
  166 + "未知审核状态(test)");
  167 + }
  168 +
  169 + @Test
  170 + public void testInvoke_throwable() {
  171 + // 准备参数
  172 + Supplier<Result<Object>> requestConsumer =
  173 + () -> new Result<>().setThrowable(new NullPointerException());
  174 + // mock 方法
  175 +
  176 + // 调用,并断言异常
  177 + assertThrows(NullPointerException.class,
  178 + () -> smsClient.invoke(requestConsumer, null));
  179 + }
  180 +
  181 + @Test
  182 + @SuppressWarnings("unchecked")
  183 + public void testInvoke_success() throws Throwable {
  184 + // 准备参数
  185 + Result<SmsSingleSend> responseResult = randomPojo(Result.class, SmsSingleSend.class, o -> o.setCode(OK));
  186 + Supplier<Result<SmsSingleSend>> requestConsumer = () -> responseResult;
  187 + Function<SmsSingleSend, SmsSendRespDTO> responseConsumer =
  188 + smsSingleSend -> new SmsSendRespDTO().setSerialNo(String.valueOf(responseResult.getData().getSid()));
  189 + // mock 方法
  190 +
  191 + // 调用
  192 + SmsCommonResult<SmsSendRespDTO> result = smsClient.invoke(requestConsumer, responseConsumer);
  193 + // 断言
  194 + assertEquals(String.valueOf(responseResult.getCode()), result.getApiCode());
  195 + assertEquals(responseResult.getMsg() + " => " + responseResult.getDetail(), result.getApiMsg());
  196 + assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
  197 + assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
  198 + assertNull(result.getApiRequestId());
  199 + assertEquals(String.valueOf(responseResult.getData().getSid()), result.getData().getSerialNo());
  200 + }
  201 +
50 202 }
... ...