支付宝 H5 Client 单元测试

This commit is contained in:
jason 2023-08-22 19:16:03 +08:00
parent 4c634245e9
commit c7f0b5c73d
3 changed files with 141 additions and 34 deletions

View File

@ -1,10 +1,12 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.ReflectUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.exception.PayException; import cn.iocoder.yudao.framework.pay.core.client.exception.PayException;
@ -16,6 +18,7 @@ import com.alipay.api.DefaultSigner;
import com.alipay.api.domain.AlipayTradeRefundModel; import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeRefundRequest; import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse; import com.alipay.api.response.AlipayTradeRefundResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatcher; import org.mockito.ArgumentMatcher;
@ -52,6 +55,12 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest {
private AbstractAlipayPayClient client; private AbstractAlipayPayClient client;
/**
* 子类需要实现该方法. 设置 client 的具体实现
*/
@BeforeEach
public abstract void setUp();
public void setClient(AbstractAlipayPayClient client) { public void setClient(AbstractAlipayPayClient client) {
this.client = client; this.client = client;
} }
@ -177,4 +186,28 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest {
// 断言 // 断言
assertThrows(PayException.class, () -> client.unifiedRefund(refundReqDTO)); assertThrows(PayException.class, () -> client.unifiedRefund(refundReqDTO));
} }
@Test
@DisplayName("支付宝 Client 统一下单, 参数校验不通过")
public void test_unified_order_param_validate() {
// 准备请求参数
String outTradeNo = randomString();
String notifyUrl = randomURL();
PayOrderUnifiedReqDTO reqDTO = randomPojo(PayOrderUnifiedReqDTO.class, o -> {
o.setOutTradeNo(outTradeNo);
o.setNotifyUrl(notifyUrl);
});
// 断言
assertThrows(ConstraintViolationException.class, () -> client.unifiedOrder(reqDTO));
}
protected PayOrderUnifiedReqDTO buildOrderUnifiedReqDTO(String notifyUrl, String outTradeNo, Integer price) {
return randomPojo(PayOrderUnifiedReqDTO.class, o -> {
o.setOutTradeNo(outTradeNo);
o.setNotifyUrl(notifyUrl);
o.setPrice(price);
o.setSubject(RandomUtil.randomString(32));
o.setBody(RandomUtil.randomString(32));
});
}
} }

View File

@ -1,6 +1,5 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.core.util.RandomUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
@ -17,8 +16,6 @@ import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatcher; import org.mockito.ArgumentMatcher;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import javax.validation.ConstraintViolationException;
import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED; import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED;
import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.WAITING; import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.WAITING;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
@ -42,11 +39,12 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest {
} }
@Test @Test
@DisplayName("支付扫描支付下单成功") @DisplayName("支付扫描支付下单成功")
public void test_unified_order_success() throws AlipayApiException { public void test_unified_order_success() throws AlipayApiException {
// 准备返回对象 // 准备返回对象
String notifyUrl = randomURL(); String notifyUrl = randomURL();
String qrCode = randomString(); String qrCode = randomString();
Integer price = randomInteger();
AlipayTradePrecreateResponse response = randomPojo(AlipayTradePrecreateResponse.class, o -> { AlipayTradePrecreateResponse response = randomPojo(AlipayTradePrecreateResponse.class, o -> {
o.setQrCode(qrCode); o.setQrCode(qrCode);
o.setSubCode(""); o.setSubCode("");
@ -58,7 +56,7 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest {
}))).thenReturn(response); }))).thenReturn(response);
// 准备请求参数 // 准备请求参数
String outTradeNo = randomString(); String outTradeNo = randomString();
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo); PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
PayOrderRespDTO resp = client.unifiedOrder(reqDTO); PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
// 断言 // 断言
@ -70,11 +68,12 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest {
} }
@Test @Test
@DisplayName("支付扫描支付,渠道返回失败") @DisplayName("支付扫描支付,渠道返回失败")
public void test_unified_order_channel_failed() throws AlipayApiException { public void test_unified_order_channel_failed() throws AlipayApiException {
String notifyUrl = randomURL(); String notifyUrl = randomURL();
String subCode = randomString(); String subCode = randomString();
String subMsg = randomString(); String subMsg = randomString();
Integer price = randomInteger();
AlipayTradePrecreateResponse response = randomPojo(AlipayTradePrecreateResponse.class, o -> { AlipayTradePrecreateResponse response = randomPojo(AlipayTradePrecreateResponse.class, o -> {
o.setSubCode(subCode); o.setSubCode(subCode);
o.setSubMsg(subMsg); o.setSubMsg(subMsg);
@ -86,7 +85,7 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest {
}))).thenReturn(response); }))).thenReturn(response);
// 准备请求参数 // 准备请求参数
String outTradeNo = randomString(); String outTradeNo = randomString();
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo); PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
PayOrderRespDTO resp = client.unifiedOrder(reqDTO); PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
// 断言 // 断言
@ -97,59 +96,38 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest {
} }
@Test @Test
@DisplayName("支付包扫描支付,抛出系统异常") @DisplayName("支付宝扫描支付, 抛出系统异常")
public void test_unified_order_throw_pay_exception() throws AlipayApiException { public void test_unified_order_throw_pay_exception() throws AlipayApiException {
// 准备请求参数 // 准备请求参数
String outTradeNo = randomString(); String outTradeNo = randomString();
String notifyUrl = randomURL(); String notifyUrl = randomURL();
Integer price = randomInteger();
// mock // mock
when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradePrecreateRequest>) request -> { when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradePrecreateRequest>) request -> {
assertEquals(notifyUrl, request.getNotifyUrl()); assertEquals(notifyUrl, request.getNotifyUrl());
return true; return true;
}))).thenThrow(new RuntimeException("系统异常")); }))).thenThrow(new RuntimeException("系统异常"));
// 准备请求参数 // 准备请求参数
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo); PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo,price);
// 断言 // 断言
assertThrows(PayException.class, () -> client.unifiedOrder(reqDTO)); assertThrows(PayException.class, () -> client.unifiedOrder(reqDTO));
} }
@Test @Test
@DisplayName("支付包扫描支付,抛出业务异常") @DisplayName("支付宝 Client 统一下单,抛出业务异常")
public void test_unified_order_throw_service_exception() throws AlipayApiException { public void test_unified_order_throw_service_exception() throws AlipayApiException {
// 准备请求参数 // 准备请求参数
String outTradeNo = randomString(); String outTradeNo = randomString();
String notifyUrl = randomURL(); String notifyUrl = randomURL();
Integer price = randomInteger();
// mock // mock
when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradePrecreateRequest>) request -> { when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradePrecreateRequest>) request -> {
assertEquals(notifyUrl, request.getNotifyUrl()); assertEquals(notifyUrl, request.getNotifyUrl());
return true; return true;
}))).thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR)); }))).thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR));
// 准备请求参数 // 准备请求参数
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo); PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
// 断言 // 断言
assertThrows(ServiceException.class, () -> client.unifiedOrder(reqDTO)); assertThrows(ServiceException.class, () -> client.unifiedOrder(reqDTO));
} }
@Test
@DisplayName("支付包扫描支付,参数校验不通过")
public void test_unified_order_param_validate() {
// 准备请求参数
String outTradeNo = randomString();
String notifyUrl = randomURL();
PayOrderUnifiedReqDTO reqDTO = randomPojo(PayOrderUnifiedReqDTO.class, o -> {
o.setOutTradeNo(outTradeNo);
o.setNotifyUrl(notifyUrl);
});
// 断言
assertThrows(ConstraintViolationException.class, () -> client.unifiedOrder(reqDTO));
}
private PayOrderUnifiedReqDTO buildOrderUnifiedReqDTO(String notifyUrl, String outTradeNo) {
return randomPojo(PayOrderUnifiedReqDTO.class, o -> {
o.setOutTradeNo(outTradeNo);
o.setNotifyUrl(notifyUrl);
o.setSubject(RandomUtil.randomString(32));
o.setBody(RandomUtil.randomString(32));
});
}
} }

View File

@ -0,0 +1,96 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.hutool.http.Method;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.InjectMocks;
import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED;
import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.WAITING;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
/**
* {@link AlipayWapPayClient} 单元测试
*
* @author jason
*/
public class AlipayWapPayClientTest extends AbstractAlipayClientTest {
/**
* 支付宝 H5 支付 Client
*/
@InjectMocks
private AlipayWapPayClient client = new AlipayWapPayClient(randomLongId(), config);
@BeforeEach
public void setUp() {
setClient(client);
}
@Test
@DisplayName("支付宝 H5 支付下单成功")
public void test_unified_order_success() throws AlipayApiException {
// 准备响应对象
String h5Body = randomString();
Integer price = randomInteger();
AlipayTradeWapPayResponse response = randomPojo(AlipayTradeWapPayResponse.class, o -> {
o.setSubCode("");
o.setBody(h5Body);
});
String notifyUrl = randomURL();
// mock
when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher<AlipayTradeWapPayRequest>) request -> {
assertInstanceOf(AlipayTradeWapPayModel.class, request.getBizModel());
AlipayTradeWapPayModel bizModel = (AlipayTradeWapPayModel) request.getBizModel();
assertEquals(String.valueOf(price / 100.0), bizModel.getTotalAmount());
assertEquals(notifyUrl, request.getNotifyUrl());
return true;
}), eq(Method.GET.name()))).thenReturn(response);
String outTradeNo = randomString();
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
assertEquals(WAITING.getStatus(), resp.getStatus());
assertEquals(PayOrderDisplayModeEnum.URL.getMode(), resp.getDisplayMode());
assertEquals(outTradeNo, resp.getOutTradeNo());
assertEquals(h5Body, resp.getDisplayContent());
assertSame(response, resp.getRawData());
}
@Test
@DisplayName("支付宝 H5 支付,渠道返回失败")
public void test_unified_order_channel_failed() throws AlipayApiException {
// 准备响应对象
String subCode = randomString();
String subMsg = randomString();
AlipayTradeWapPayResponse response = randomPojo(AlipayTradeWapPayResponse.class, o -> {
o.setSubCode(subCode);
o.setSubMsg(subMsg);
});
// mock
when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher<AlipayTradeWapPayRequest>) request -> true),
eq(Method.GET.name()))).thenReturn(response);
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger());
PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
// 断言
assertEquals(CLOSED.getStatus(), resp.getStatus());
assertEquals(subCode, resp.getChannelErrorCode());
assertEquals(subMsg, resp.getChannelErrorMsg());
assertSame(response, resp.getRawData());
}
}