Commit 35c1ba44d32e5da4df3429eeda1a06d09248515e

Authored by YunaiV
1 parent f5c5d383

优化 AbstractAlipayClientTest、AlipayBarPayClientTest 的方法命名,补全 assert 断言

yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java
... ... @@ -27,6 +27,7 @@ import com.alipay.api.request.AlipayTradeRefundRequest;
27 27 import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
28 28 import com.alipay.api.response.AlipayTradeQueryResponse;
29 29 import com.alipay.api.response.AlipayTradeRefundResponse;
  30 +import lombok.Getter;
30 31 import lombok.SneakyThrows;
31 32 import lombok.extern.slf4j.Slf4j;
32 33  
... ... @@ -47,6 +48,7 @@ import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER;
47 48 @Slf4j
48 49 public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPayClientConfig> {
49 50  
  51 + @Getter // 仅用于单测场景
50 52 protected DefaultAlipayClient client;
51 53  
52 54 public AbstractAlipayPayClient(Long channelId, String channelCode, AlipayPayClientConfig config) {
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClient.java
... ... @@ -13,6 +13,8 @@ import com.alipay.api.request.AlipayTradePayRequest;
13 13 import com.alipay.api.response.AlipayTradePayResponse;
14 14 import lombok.extern.slf4j.Slf4j;
15 15  
  16 +import java.time.LocalDateTime;
  17 +
16 18 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
17 19 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
18 20  
... ... @@ -63,8 +65,10 @@ public class AlipayBarPayClient extends AbstractAlipayPayClient {
63 65 return buildClosedPayOrderRespDTO(reqDTO, response);
64 66 }
65 67 if ("10000".equals(response.getCode())) { // 免密支付
66   - return PayOrderRespDTO.successOf(response.getTradeNo(), response.getBuyerUserId(), LocalDateTimeUtil.of(response.getGmtPayment()),
67   - response.getOutTradeNo(), response);
  68 + LocalDateTime successTime = LocalDateTimeUtil.of(response.getGmtPayment());
  69 + return PayOrderRespDTO.successOf(response.getTradeNo(), response.getBuyerUserId(), successTime,
  70 + response.getOutTradeNo(), response)
  71 + .setDisplayMode(displayMode).setDisplayContent("");
68 72 }
69 73 // 大额支付,需要用户输入密码,所以返回 waiting。此时,前端一般会进行轮询
70 74 return PayOrderRespDTO.waitingOf(displayMode, "",
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClientTest.java
... ... @@ -2,7 +2,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
2 2  
3 3 import cn.hutool.core.date.LocalDateTimeUtil;
4 4 import cn.hutool.core.util.RandomUtil;
5   -import cn.hutool.core.util.ReflectUtil;
6 5 import cn.iocoder.yudao.framework.common.exception.ServiceException;
7 6 import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
8 7 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
... ... @@ -18,6 +17,7 @@ import com.alipay.api.DefaultSigner;
18 17 import com.alipay.api.domain.AlipayTradeRefundModel;
19 18 import com.alipay.api.request.AlipayTradeRefundRequest;
20 19 import com.alipay.api.response.AlipayTradeRefundResponse;
  20 +import lombok.Setter;
21 21 import org.junit.jupiter.api.BeforeEach;
22 22 import org.junit.jupiter.api.DisplayName;
23 23 import org.junit.jupiter.api.Test;
... ... @@ -34,25 +34,26 @@ import static org.mockito.ArgumentMatchers.argThat;
34 34 import static org.mockito.Mockito.when;
35 35  
36 36 /**
  37 + * 支付宝 Client 的测试基类
  38 + *
37 39 * @author jason
38 40 */
39 41 public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest {
40 42  
41   - private final String privateKey = randomString();
42   -
43   - protected AlipayPayClientConfig config = randomPojo(AlipayPayClientConfig.class, t -> {
44   - t.setServerUrl(randomURL());
45   - t.setPrivateKey(privateKey);
46   - t.setMode(MODE_PUBLIC_KEY);
47   - t.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT);
48   - t.setAppCertContent("");
49   - t.setAlipayPublicCertContent("");
50   - t.setRootCertContent("");
  43 + protected AlipayPayClientConfig config = randomPojo(AlipayPayClientConfig.class, o -> {
  44 + o.setServerUrl(randomURL());
  45 + o.setPrivateKey(randomString());
  46 + o.setMode(MODE_PUBLIC_KEY);
  47 + o.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT);
  48 + o.setAppCertContent("");
  49 + o.setAlipayPublicCertContent("");
  50 + o.setRootCertContent("");
51 51 });
52 52  
53 53 @Mock
54 54 protected DefaultAlipayClient defaultAlipayClient;
55 55  
  56 + @Setter
56 57 private AbstractAlipayPayClient client;
57 58  
58 59 /**
... ... @@ -61,24 +62,22 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest {
61 62 @BeforeEach
62 63 public abstract void setUp();
63 64  
64   - public void setClient(AbstractAlipayPayClient client) {
65   - this.client = client;
66   - }
67   -
68 65 @Test
69 66 @DisplayName("支付宝 Client 初始化")
70   - public void test_do_init() {
  67 + public void testDoInit() {
  68 + // 调用
71 69 client.doInit();
72   - DefaultAlipayClient realClient = (DefaultAlipayClient) ReflectUtil.getFieldValue(client, "client");
  70 + // 断言
  71 + DefaultAlipayClient realClient = client.getClient();
73 72 assertNotSame(defaultAlipayClient, realClient);
74 73 assertInstanceOf(DefaultSigner.class, realClient.getSigner());
75   - assertEquals(privateKey, ((DefaultSigner) realClient.getSigner()).getPrivateKey());
  74 + assertEquals(config.getPrivateKey(), ((DefaultSigner) realClient.getSigner()).getPrivateKey());
76 75 }
77 76  
78 77 @Test
79   - @DisplayName("支付宝 Client 统一退款成功")
80   - public void test_unified_refund_success() throws AlipayApiException {
81   - // 准备返回对象
  78 + @DisplayName("支付宝 Client 统一退款:成功")
  79 + public void testUnifiedRefund_success() throws AlipayApiException {
  80 + // mock 方法
82 81 String notifyUrl = randomURL();
83 82 Date refundTime = randomDate();
84 83 String outRefundNo = randomString();
... ... @@ -88,7 +87,6 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest {
88 87 o.setSubCode("");
89 88 o.setGmtRefundPay(refundTime);
90 89 });
91   - // mock
92 90 when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> {
93 91 assertInstanceOf(AlipayTradeRefundModel.class, request.getBizModel());
94 92 AlipayTradeRefundModel bizModel = (AlipayTradeRefundModel) request.getBizModel();
... ... @@ -104,19 +102,23 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest {
104 102 o.setNotifyUrl(notifyUrl);
105 103 o.setRefundPrice(refundAmount);
106 104 });
  105 +
  106 + // 调用
107 107 PayRefundRespDTO resp = client.unifiedRefund(refundReqDTO);
108 108 // 断言
109 109 assertEquals(PayRefundStatusRespEnum.SUCCESS.getStatus(), resp.getStatus());
  110 + assertEquals(outRefundNo, resp.getOutRefundNo());
110 111 assertNull(resp.getChannelRefundNo());
111 112 assertEquals(LocalDateTimeUtil.of(refundTime), resp.getSuccessTime());
112   - assertEquals(outRefundNo, resp.getOutRefundNo());
113 113 assertSame(response, resp.getRawData());
  114 + assertNull(resp.getChannelErrorCode());
  115 + assertNull(resp.getChannelErrorMsg());
114 116 }
115 117  
116 118 @Test
117   - @DisplayName("支付宝 Client 统一退款,渠道返回失败")
  119 + @DisplayName("支付宝 Client 统一退款:渠道返回失败")
118 120 public void test_unified_refund_channel_failed() throws AlipayApiException {
119   - // 准备返回对象
  121 + // mock 方法
120 122 String notifyUrl = randomURL();
121 123 String subCode = randomString();
122 124 String subMsg = randomString();
... ... @@ -124,7 +126,6 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest {
124 126 o.setSubCode(subCode);
125 127 o.setSubMsg(subMsg);
126 128 });
127   - // mock
128 129 when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> {
129 130 assertInstanceOf(AlipayTradeRefundModel.class, request.getBizModel());
130 131 return true;
... ... @@ -137,59 +138,64 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest {
137 138 o.setOutTradeNo(outTradeNo);
138 139 o.setNotifyUrl(notifyUrl);
139 140 });
  141 +
  142 + // 调用
140 143 PayRefundRespDTO resp = client.unifiedRefund(refundReqDTO);
141 144 // 断言
142 145 assertEquals(PayRefundStatusRespEnum.FAILURE.getStatus(), resp.getStatus());
  146 + assertEquals(outRefundNo, resp.getOutRefundNo());
143 147 assertNull(resp.getChannelRefundNo());
144   - assertEquals(subCode, resp.getChannelErrorCode());
145   - assertEquals(subMsg, resp.getChannelErrorMsg());
146 148 assertNull(resp.getSuccessTime());
147   - assertEquals(outRefundNo, resp.getOutRefundNo());
148 149 assertSame(response, resp.getRawData());
  150 + assertEquals(subCode, resp.getChannelErrorCode());
  151 + assertEquals(subMsg, resp.getChannelErrorMsg());
149 152 }
150 153  
151 154 @Test
152   - @DisplayName("支付宝 Client 统一退款,参数校验不通过")
153   - public void test_unified_refund_param_validate() {
  155 + @DisplayName("支付宝 Client 统一退款:参数校验不通过")
  156 + public void testUnifiedRefund_paramInvalidate() {
154 157 // 准备请求参数
155 158 String notifyUrl = randomURL();
156 159 PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
157 160 o.setOutTradeNo("");
158 161 o.setNotifyUrl(notifyUrl);
159 162 });
160   - // 断言
  163 +
  164 + // 调用,并断言
161 165 assertThrows(ConstraintViolationException.class, () -> client.unifiedRefund(refundReqDTO));
162 166 }
163 167  
164 168 @Test
165   - @DisplayName("支付宝 Client 统一退款,抛出业务异常")
166   - public void test_unified_refund_throw_service_exception() throws AlipayApiException {
  169 + @DisplayName("支付宝 Client 统一退款:抛出业务异常")
  170 + public void testUnifiedRefund_throwServiceException() throws AlipayApiException {
167 171 // mock
168 172 when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> true)))
169 173 .thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR));
170 174 // 准备请求参数
171 175 String notifyUrl = randomURL();
172 176 PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> o.setNotifyUrl(notifyUrl));
173   - // 断言
  177 +
  178 + // 调用,并断言
174 179 assertThrows(ServiceException.class, () -> client.unifiedRefund(refundReqDTO));
175 180 }
176 181  
177 182 @Test
178   - @DisplayName("支付宝 Client 统一退款,抛出系统异常")
179   - public void test_unified_refund_throw_pay_exception() throws AlipayApiException {
  183 + @DisplayName("支付宝 Client 统一退款:抛出系统异常")
  184 + public void testUnifiedRefund_throwPayException() throws AlipayApiException {
180 185 // mock
181 186 when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> true)))
182 187 .thenThrow(new RuntimeException("系统异常"));
183 188 // 准备请求参数
184 189 String notifyUrl = randomURL();
185 190 PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> o.setNotifyUrl(notifyUrl));
186   - // 断言
  191 +
  192 + // 调用,并断言
187 193 assertThrows(PayException.class, () -> client.unifiedRefund(refundReqDTO));
188 194 }
189 195  
190 196 @Test
191   - @DisplayName("支付宝 Client 统一下单, 参数校验不通过")
192   - public void test_unified_order_param_validate() {
  197 + @DisplayName("支付宝 Client 统一下单:参数校验不通过")
  198 + public void testUnifiedOrder_paramInvalidate() {
193 199 // 准备请求参数
194 200 String outTradeNo = randomString();
195 201 String notifyUrl = randomURL();
... ... @@ -197,7 +203,8 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest {
197 203 o.setOutTradeNo(outTradeNo);
198 204 o.setNotifyUrl(notifyUrl);
199 205 });
200   - // 断言
  206 +
  207 + // 调用,并断言
201 208 assertThrows(ConstraintViolationException.class, () -> client.unifiedOrder(reqDTO));
202 209 }
203 210  
... ... @@ -210,4 +217,5 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest {
210 217 o.setBody(RandomUtil.randomString(32));
211 218 });
212 219 }
  220 +
213 221 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClientTest.java
... ... @@ -28,7 +28,7 @@ import static org.mockito.ArgumentMatchers.argThat;
28 28 import static org.mockito.Mockito.when;
29 29  
30 30 /**
31   - * {@link AlipayBarPayClient} 单元测试
  31 + * {@link AlipayBarPayClient} 单元测试
32 32 *
33 33 * @author jason
34 34 */
... ... @@ -44,16 +44,14 @@ public class AlipayBarPayClientTest extends AbstractAlipayClientTest {
44 44 }
45 45  
46 46 @Test
47   - @DisplayName("支付宝条码支付,非免密码支付下单成功")
48   - public void test_unified_order_success() throws AlipayApiException {
  47 + @DisplayName("支付宝条码支付:非免密码支付下单成功")
  48 + public void testUnifiedOrder_success() throws AlipayApiException {
  49 + // mock 方法
49 50 String outTradeNo = randomString();
50 51 String notifyUrl = randomURL();
51 52 Integer price = randomInteger();
52 53 String authCode = randomString();
53   - // 准备返回对象
54 54 AlipayTradePayResponse response = randomPojo(AlipayTradePayResponse.class, o -> o.setSubCode(""));
55   -
56   - // mock
57 55 when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradePayRequest>) request -> {
58 56 assertInstanceOf(AlipayTradePayModel.class, request.getBizModel());
59 57 assertEquals(notifyUrl, request.getNotifyUrl());
... ... @@ -65,28 +63,33 @@ public class AlipayBarPayClientTest extends AbstractAlipayClientTest {
65 63 }))).thenReturn(response);
66 64 // 准备请求参数
67 65 PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
68   - // 设置条码
69 66 Map<String, String> extraParam = new HashMap<>();
70 67 extraParam.put("auth_code", authCode);
71 68 reqDTO.setChannelExtras(extraParam);
72   - // 下单请求
  69 +
  70 + // 调用方法
73 71 PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
74 72 // 断言
75 73 assertEquals(WAITING.getStatus(), resp.getStatus());
76   - assertEquals(PayOrderDisplayModeEnum.BAR_CODE.getMode(), resp.getDisplayMode());
77 74 assertEquals(outTradeNo, resp.getOutTradeNo());
  75 + assertNull(resp.getChannelOrderNo());
  76 + assertNull(resp.getChannelUserId());
  77 + assertNull(resp.getSuccessTime());
  78 + assertEquals(PayOrderDisplayModeEnum.BAR_CODE.getMode(), resp.getDisplayMode());
78 79 assertEquals("", resp.getDisplayContent());
79 80 assertSame(response, resp.getRawData());
  81 + assertNull(resp.getChannelErrorCode());
  82 + assertNull(resp.getChannelErrorMsg());
80 83 }
81 84  
82 85 @Test
83   - @DisplayName("支付宝条码支付,免密码支付下单成功")
84   - public void test_unified_order_code_10000_success() throws AlipayApiException {
  86 + @DisplayName("支付宝条码支付:免密码支付下单成功")
  87 + public void testUnifiedOrder_code10000Success() throws AlipayApiException {
  88 + // mock 方法
85 89 String outTradeNo = randomString();
86 90 String channelNo = randomString();
87 91 String channelUserId = randomString();
88 92 Date payTime = randomDate();
89   - // 准备返回对象
90 93 AlipayTradePayResponse response = randomPojo(AlipayTradePayResponse.class, o -> {
91 94 o.setSubCode("");
92 95 o.setCode("10000");
... ... @@ -95,16 +98,15 @@ public class AlipayBarPayClientTest extends AbstractAlipayClientTest {
95 98 o.setBuyerUserId(channelUserId);
96 99 o.setGmtPayment(payTime);
97 100 });
98   - // mock
99 101 when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradePayRequest>) request -> true)))
100 102 .thenReturn(response);
101 103 // 准备请求参数
102 104 String authCode = randomString();
103 105 PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), outTradeNo, randomInteger());
104   - // 设置条码
105 106 Map<String, String> extraParam = new HashMap<>();
106 107 extraParam.put("auth_code", authCode);
107 108 reqDTO.setChannelExtras(extraParam);
  109 +
108 110 // 下单请求
109 111 PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
110 112 // 断言
... ... @@ -113,45 +115,56 @@ public class AlipayBarPayClientTest extends AbstractAlipayClientTest {
113 115 assertEquals(channelNo, resp.getChannelOrderNo());
114 116 assertEquals(channelUserId, resp.getChannelUserId());
115 117 assertEquals(LocalDateTimeUtil.of(payTime), resp.getSuccessTime());
  118 + assertEquals(PayOrderDisplayModeEnum.BAR_CODE.getMode(), resp.getDisplayMode());
  119 + assertEquals("", resp.getDisplayContent());
116 120 assertSame(response, resp.getRawData());
  121 + assertNull(resp.getChannelErrorCode());
  122 + assertNull(resp.getChannelErrorMsg());
117 123 }
118 124  
119 125 @Test
120   - @DisplayName("支付宝条码支付,没有传条码")
121   - public void test_unified_order_empty_auth_code() {
  126 + @DisplayName("支付宝条码支付:没有传条码")
  127 + public void testUnifiedOrder_emptyAuthCode() {
  128 + // 准备参数
122 129 PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger());
123   - // 断言
  130 +
  131 + // 调用,并断言
124 132 assertThrows(ServiceException.class, () -> client.unifiedOrder(reqDTO));
125 133 }
126 134  
127 135 @Test
128   - @DisplayName("支付宝条码支付,渠道返回失败")
  136 + @DisplayName("支付宝条码支付:渠道返回失败")
129 137 public void test_unified_order_channel_failed() throws AlipayApiException {
130   - // 准备响应对象
  138 + // mock 方法
131 139 String subCode = randomString();
132 140 String subMsg = randomString();
133 141 AlipayTradePayResponse response = randomPojo(AlipayTradePayResponse.class, o -> {
134 142 o.setSubCode(subCode);
135 143 o.setSubMsg(subMsg);
136 144 });
137   - // mock
138 145 when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradePayRequest>) request -> true)))
139 146 .thenReturn(response);
140 147 // 准备请求参数
141 148 String authCode = randomString();
142 149 String outTradeNo = randomString();
143 150 PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), outTradeNo, randomInteger());
144   - // 设置条码
145 151 Map<String, String> extraParam = new HashMap<>();
146 152 extraParam.put("auth_code", authCode);
147 153 reqDTO.setChannelExtras(extraParam);
148   - // 下单请求
  154 +
  155 + // 调用方法
149 156 PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
150 157 // 断言
151 158 assertEquals(CLOSED.getStatus(), resp.getStatus());
  159 + assertEquals(outTradeNo, resp.getOutTradeNo());
  160 + assertNull(resp.getChannelOrderNo());
  161 + assertNull(resp.getChannelUserId());
  162 + assertNull(resp.getSuccessTime());
  163 + assertNull(resp.getDisplayMode());
  164 + assertNull(resp.getDisplayContent());
  165 + assertSame(response, resp.getRawData());
152 166 assertEquals(subCode, resp.getChannelErrorCode());
153 167 assertEquals(subMsg, resp.getChannelErrorMsg());
154   - assertSame(response, resp.getRawData());
155   -
156 168 }
  169 +
157 170 }
... ...