Commit 6fbf7b261b49b63ec68047822ed68c90f16ffe3c

Authored by jason
1 parent d3c02f2a

扫码支付统一退款单元测试, 修复退款失败,渠道错误未赋值bug

yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java
... ... @@ -148,7 +148,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
148 148 // 2.1 执行请求
149 149 AlipayTradeRefundResponse response = client.execute(request);
150 150 if (!response.isSuccess()) {
151   - return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response);
  151 + return PayRefundRespDTO.failureOf(response.getSubCode(), response.getSubMsg(), reqDTO.getOutRefundNo(), response);
152 152 }
153 153 // 2.2 创建返回结果
154 154 // 支付宝只要退款调用返回 success,就认为退款成功,不需要回调。具体可见 parseNotify 方法的说明。
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java
1 1 package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
2 2  
  3 +import cn.hutool.core.date.LocalDateTimeUtil;
3 4 import cn.hutool.core.util.RandomUtil;
4 5 import cn.hutool.core.util.ReflectUtil;
5 6 import cn.iocoder.yudao.framework.common.exception.ServiceException;
... ... @@ -7,19 +8,27 @@ import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstant
7 8 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
8 9 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
9 10 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
  11 +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
  12 +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
10 13 import cn.iocoder.yudao.framework.pay.core.client.exception.PayException;
11 14 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
  15 +import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
12 16 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
13 17 import com.alipay.api.AlipayApiException;
14 18 import com.alipay.api.DefaultAlipayClient;
  19 +import com.alipay.api.domain.AlipayTradeRefundModel;
15 20 import com.alipay.api.request.AlipayTradePrecreateRequest;
  21 +import com.alipay.api.request.AlipayTradeRefundRequest;
16 22 import com.alipay.api.response.AlipayTradePrecreateResponse;
  23 +import com.alipay.api.response.AlipayTradeRefundResponse;
  24 +import org.junit.jupiter.api.DisplayName;
17 25 import org.junit.jupiter.api.Test;
18 26 import org.mockito.ArgumentMatcher;
19 27 import org.mockito.InjectMocks;
20 28 import org.mockito.Mock;
21 29  
22 30 import javax.validation.ConstraintViolationException;
  31 +import java.util.Date;
23 32  
24 33 import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_PUBLIC_KEY;
25 34 import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED;
... ... @@ -51,13 +60,14 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
51 60 private DefaultAlipayClient defaultAlipayClient;
52 61  
53 62 @Test
54   - public void testDoInit() {
  63 + public void test_do_init() {
55 64 client.doInit();
56 65 assertNotSame(defaultAlipayClient, ReflectUtil.getFieldValue(client, "defaultAlipayClient"));
57 66 }
58 67  
59 68 @Test
60   - public void testUnifiedOrderSuccess() throws AlipayApiException {
  69 + @DisplayName("支付包扫描支付下单成功")
  70 + public void test_unified_order_success() throws AlipayApiException {
61 71 // 准备返回对象
62 72 String notifyUrl = randomURL();
63 73 String qrCode = randomString();
... ... @@ -84,7 +94,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
84 94 }
85 95  
86 96 @Test
87   - public void testUnifiedOrderChannelFailed() throws AlipayApiException {
  97 + @DisplayName("支付包扫描支付,渠道返回失败")
  98 + public void test_unified_order_channel_failed() throws AlipayApiException {
88 99 String notifyUrl = randomURL();
89 100 String subCode = randomString();
90 101 String subMsg = randomString();
... ... @@ -110,7 +121,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
110 121 }
111 122  
112 123 @Test
113   - public void test_unifiedOrder_throw_pay_exception() throws AlipayApiException {
  124 + @DisplayName("支付包扫描支付,抛出系统异常")
  125 + public void test_unified_order_throw_pay_exception() throws AlipayApiException {
114 126 // 准备请求参数
115 127 String outTradeNo = randomString();
116 128 String notifyUrl = randomURL();
... ... @@ -126,7 +138,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
126 138 }
127 139  
128 140 @Test
129   - public void test_unifiedOrder_throw_service_exception() throws AlipayApiException {
  141 + @DisplayName("支付包扫描支付,抛出业务异常")
  142 + public void test_unified_order_throw_service_exception() throws AlipayApiException {
130 143 // 准备请求参数
131 144 String outTradeNo = randomString();
132 145 String notifyUrl = randomURL();
... ... @@ -142,7 +155,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
142 155 }
143 156  
144 157 @Test
145   - public void test_unifiedOrder_param_validate() {
  158 + @DisplayName("支付包扫描支付,参数校验不通过")
  159 + public void test_unified_order_param_validate() {
146 160 // 准备请求参数
147 161 String outTradeNo = randomString();
148 162 String notifyUrl = randomURL();
... ... @@ -162,4 +176,119 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
162 176 o.setBody(RandomUtil.randomString(32));
163 177 });
164 178 }
  179 +
  180 + @Test
  181 + @DisplayName("支付包扫描退款成功")
  182 + public void test_unified_refund_success() throws AlipayApiException {
  183 + // 准备返回对象
  184 + String notifyUrl = randomURL();
  185 + Date refundTime = randomDate();
  186 + String outRefundNo = randomString();
  187 + String outTradeNo = randomString();
  188 + Integer refundAmount = randomInteger();
  189 + AlipayTradeRefundResponse response = randomPojo(AlipayTradeRefundResponse.class, o -> {
  190 + o.setSubCode("");
  191 + o.setGmtRefundPay(refundTime);
  192 + });
  193 + // mock
  194 + when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> {
  195 + assertInstanceOf(AlipayTradeRefundModel.class, request.getBizModel());
  196 + AlipayTradeRefundModel bizModel = (AlipayTradeRefundModel) request.getBizModel();
  197 + assertEquals(outRefundNo, bizModel.getOutRequestNo());
  198 + assertEquals(outTradeNo, bizModel.getOutTradeNo());
  199 + assertEquals(String.valueOf(refundAmount / 100.0), bizModel.getRefundAmount());
  200 + return true;
  201 + }))).thenReturn(response);
  202 + // 准备请求参数
  203 + PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
  204 + o.setOutRefundNo(outRefundNo);
  205 + o.setOutTradeNo(outTradeNo);
  206 + o.setNotifyUrl(notifyUrl);
  207 + o.setRefundPrice(refundAmount);
  208 + });
  209 + PayRefundRespDTO resp = client.unifiedRefund(refundReqDTO);
  210 + // 断言
  211 + assertEquals(PayRefundStatusRespEnum.SUCCESS.getStatus(), resp.getStatus());
  212 + assertNull(resp.getChannelRefundNo());
  213 + assertEquals(LocalDateTimeUtil.of(refundTime), resp.getSuccessTime());
  214 + assertEquals(outRefundNo, resp.getOutRefundNo());
  215 + assertSame(response, resp.getRawData());
  216 + }
  217 +
  218 + @Test
  219 + @DisplayName("支付包扫描退款,渠道返回失败")
  220 + public void test_unified_refund_channel_failed() throws AlipayApiException {
  221 + // 准备返回对象
  222 + String notifyUrl = randomURL();
  223 + String subCode = randomString();
  224 + String subMsg = randomString();
  225 + AlipayTradeRefundResponse response = randomPojo(AlipayTradeRefundResponse.class, o -> {
  226 + o.setSubCode(subCode);
  227 + o.setSubMsg(subMsg);
  228 + });
  229 + // mock
  230 + when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> {
  231 + assertInstanceOf(AlipayTradeRefundModel.class, request.getBizModel());
  232 + return true;
  233 + }))).thenReturn(response);
  234 + // 准备请求参数
  235 + String outRefundNo = randomString();
  236 + String outTradeNo = randomString();
  237 + PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
  238 + o.setOutRefundNo(outRefundNo);
  239 + o.setOutTradeNo(outTradeNo);
  240 + o.setNotifyUrl(notifyUrl);
  241 + });
  242 + PayRefundRespDTO resp = client.unifiedRefund(refundReqDTO);
  243 + // 断言
  244 + assertEquals(PayRefundStatusRespEnum.FAILURE.getStatus(), resp.getStatus());
  245 + assertNull(resp.getChannelRefundNo());
  246 + assertEquals(subCode, resp.getChannelErrorCode());
  247 + assertEquals(subMsg, resp.getChannelErrorMsg());
  248 + assertNull(resp.getSuccessTime());
  249 + assertEquals(outRefundNo, resp.getOutRefundNo());
  250 + assertSame(response, resp.getRawData());
  251 + }
  252 +
  253 + @Test
  254 + @DisplayName("支付包扫描退款,参数校验不通过")
  255 + public void test_unified_refund_param_validate() {
  256 + // 准备请求参数
  257 + String notifyUrl = randomURL();
  258 + PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
  259 + o.setOutTradeNo("");
  260 + o.setNotifyUrl(notifyUrl);
  261 + });
  262 + // 断言
  263 + assertThrows(ConstraintViolationException.class, () -> client.unifiedRefund(refundReqDTO));
  264 + }
  265 +
  266 + @Test
  267 + @DisplayName("支付包扫描退款,抛出业务异常")
  268 + public void test_unified_refund_throw_service_exception() throws AlipayApiException {
  269 + // mock
  270 + when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> true)))
  271 + .thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR));
  272 + // 准备请求参数
  273 + String notifyUrl = randomURL();
  274 + PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
  275 + o.setNotifyUrl(notifyUrl);
  276 + });
  277 + // 断言
  278 + assertThrows(ServiceException.class, () -> client.unifiedRefund(refundReqDTO));
  279 + }
  280 + @Test
  281 + @DisplayName("支付包扫描退款,抛出系统异常")
  282 + public void test_unified_refund_throw_pay_exception() throws AlipayApiException {
  283 + // mock
  284 + when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> true)))
  285 + .thenThrow(new RuntimeException("系统异常"));
  286 + // 准备请求参数
  287 + String notifyUrl = randomURL();
  288 + PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
  289 + o.setNotifyUrl(notifyUrl);
  290 + });
  291 + // 断言
  292 + assertThrows(PayException.class, () -> client.unifiedRefund(refundReqDTO));
  293 + }
165 294 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentServiceImplTest.java
... ... @@ -7,16 +7,14 @@ import org.junit.jupiter.api.BeforeEach;
7 7 import org.junit.jupiter.api.Test;
8 8 import org.mockito.InjectMocks;
9 9 import org.mockito.Mock;
10   -import org.mockito.Mockito;
11 10  
12 11 import java.util.ArrayList;
13 12 import java.util.List;
14 13  
15 14 import static cn.iocoder.yudao.module.promotion.enums.decorate.DecorateComponentEnum.ROLLING_NEWS;
16 15 import static cn.iocoder.yudao.module.promotion.enums.decorate.DecoratePageEnum.INDEX;
17   -import static org.mockito.ArgumentMatchers.eq;
18 16  
19   -// TODO @芋艿:后续 review 下
  17 +// TODO 待完成 @芋艿:后续 review 下
20 18 /**
21 19 * @author jason
22 20 */
... ... @@ -41,6 +39,6 @@ public class DecorateComponentServiceImplTest extends BaseMockitoUnitTest {
41 39 .setCode(ROLLING_NEWS.getCode()).setId(1L);
42 40 list.add(decorateDO);
43 41 //mock 方法
44   - Mockito.when(decorateComponentMapper.selectListByPageAndStatus(eq(1))).thenReturn(list);
  42 + //Mockito.when(decorateComponentMapper.selectListByPageAndStatus(eq(1))).thenReturn(list);
45 43 }
46 44 }
... ...