mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-11-04 16:17:40 +08:00 
			
		
		
		
	扫码支付统一退款单元测试, 修复退款失败,渠道错误未赋值bug
This commit is contained in:
		@ -148,7 +148,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
 | 
			
		||||
        // 2.1 执行请求
 | 
			
		||||
        AlipayTradeRefundResponse response = client.execute(request);
 | 
			
		||||
        if (!response.isSuccess()) {
 | 
			
		||||
            return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response);
 | 
			
		||||
            return PayRefundRespDTO.failureOf(response.getSubCode(), response.getSubMsg(), reqDTO.getOutRefundNo(), response);
 | 
			
		||||
        }
 | 
			
		||||
        // 2.2 创建返回结果
 | 
			
		||||
        // 支付宝只要退款调用返回 success,就认为退款成功,不需要回调。具体可见 parseNotify 方法的说明。
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.date.LocalDateTimeUtil;
 | 
			
		||||
import cn.hutool.core.util.RandomUtil;
 | 
			
		||||
import cn.hutool.core.util.ReflectUtil;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
 | 
			
		||||
@ -7,19 +8,27 @@ import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstant
 | 
			
		||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
 | 
			
		||||
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.client.dto.refund.PayRefundRespDTO;
 | 
			
		||||
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.enums.order.PayOrderDisplayModeEnum;
 | 
			
		||||
import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
 | 
			
		||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
 | 
			
		||||
import com.alipay.api.AlipayApiException;
 | 
			
		||||
import com.alipay.api.DefaultAlipayClient;
 | 
			
		||||
import com.alipay.api.domain.AlipayTradeRefundModel;
 | 
			
		||||
import com.alipay.api.request.AlipayTradePrecreateRequest;
 | 
			
		||||
import com.alipay.api.request.AlipayTradeRefundRequest;
 | 
			
		||||
import com.alipay.api.response.AlipayTradePrecreateResponse;
 | 
			
		||||
import com.alipay.api.response.AlipayTradeRefundResponse;
 | 
			
		||||
import org.junit.jupiter.api.DisplayName;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
import org.mockito.ArgumentMatcher;
 | 
			
		||||
import org.mockito.InjectMocks;
 | 
			
		||||
import org.mockito.Mock;
 | 
			
		||||
 | 
			
		||||
import javax.validation.ConstraintViolationException;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_PUBLIC_KEY;
 | 
			
		||||
import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED;
 | 
			
		||||
@ -51,13 +60,14 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
 | 
			
		||||
    private DefaultAlipayClient defaultAlipayClient;
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testDoInit() {
 | 
			
		||||
    public void test_do_init() {
 | 
			
		||||
        client.doInit();
 | 
			
		||||
        assertNotSame(defaultAlipayClient, ReflectUtil.getFieldValue(client, "defaultAlipayClient"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testUnifiedOrderSuccess() throws AlipayApiException {
 | 
			
		||||
    @DisplayName("支付包扫描支付下单成功")
 | 
			
		||||
    public void test_unified_order_success() throws AlipayApiException {
 | 
			
		||||
        // 准备返回对象
 | 
			
		||||
        String notifyUrl = randomURL();
 | 
			
		||||
        String qrCode = randomString();
 | 
			
		||||
@ -84,7 +94,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testUnifiedOrderChannelFailed() throws AlipayApiException {
 | 
			
		||||
    @DisplayName("支付包扫描支付,渠道返回失败")
 | 
			
		||||
    public void test_unified_order_channel_failed() throws AlipayApiException {
 | 
			
		||||
        String notifyUrl = randomURL();
 | 
			
		||||
        String subCode = randomString();
 | 
			
		||||
        String subMsg = randomString();
 | 
			
		||||
@ -110,7 +121,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void test_unifiedOrder_throw_pay_exception() throws AlipayApiException {
 | 
			
		||||
    @DisplayName("支付包扫描支付,抛出系统异常")
 | 
			
		||||
    public void test_unified_order_throw_pay_exception() throws AlipayApiException {
 | 
			
		||||
        // 准备请求参数
 | 
			
		||||
        String outTradeNo = randomString();
 | 
			
		||||
        String notifyUrl = randomURL();
 | 
			
		||||
@ -126,7 +138,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void test_unifiedOrder_throw_service_exception() throws AlipayApiException {
 | 
			
		||||
    @DisplayName("支付包扫描支付,抛出业务异常")
 | 
			
		||||
    public void test_unified_order_throw_service_exception() throws AlipayApiException {
 | 
			
		||||
        // 准备请求参数
 | 
			
		||||
        String outTradeNo = randomString();
 | 
			
		||||
        String notifyUrl = randomURL();
 | 
			
		||||
@ -142,7 +155,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void test_unifiedOrder_param_validate() {
 | 
			
		||||
    @DisplayName("支付包扫描支付,参数校验不通过")
 | 
			
		||||
    public void test_unified_order_param_validate() {
 | 
			
		||||
        // 准备请求参数
 | 
			
		||||
        String outTradeNo = randomString();
 | 
			
		||||
        String notifyUrl = randomURL();
 | 
			
		||||
@ -162,4 +176,119 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
 | 
			
		||||
            o.setBody(RandomUtil.randomString(32));
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @DisplayName("支付包扫描退款成功")
 | 
			
		||||
    public void test_unified_refund_success() throws AlipayApiException {
 | 
			
		||||
        // 准备返回对象
 | 
			
		||||
        String notifyUrl = randomURL();
 | 
			
		||||
        Date refundTime = randomDate();
 | 
			
		||||
        String outRefundNo = randomString();
 | 
			
		||||
        String outTradeNo = randomString();
 | 
			
		||||
        Integer refundAmount = randomInteger();
 | 
			
		||||
        AlipayTradeRefundResponse response = randomPojo(AlipayTradeRefundResponse.class, o -> {
 | 
			
		||||
            o.setSubCode("");
 | 
			
		||||
            o.setGmtRefundPay(refundTime);
 | 
			
		||||
        });
 | 
			
		||||
        // mock
 | 
			
		||||
        when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> {
 | 
			
		||||
            assertInstanceOf(AlipayTradeRefundModel.class, request.getBizModel());
 | 
			
		||||
            AlipayTradeRefundModel bizModel = (AlipayTradeRefundModel) request.getBizModel();
 | 
			
		||||
            assertEquals(outRefundNo, bizModel.getOutRequestNo());
 | 
			
		||||
            assertEquals(outTradeNo, bizModel.getOutTradeNo());
 | 
			
		||||
            assertEquals(String.valueOf(refundAmount / 100.0), bizModel.getRefundAmount());
 | 
			
		||||
            return true;
 | 
			
		||||
        }))).thenReturn(response);
 | 
			
		||||
        // 准备请求参数
 | 
			
		||||
        PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
 | 
			
		||||
            o.setOutRefundNo(outRefundNo);
 | 
			
		||||
            o.setOutTradeNo(outTradeNo);
 | 
			
		||||
            o.setNotifyUrl(notifyUrl);
 | 
			
		||||
            o.setRefundPrice(refundAmount);
 | 
			
		||||
        });
 | 
			
		||||
        PayRefundRespDTO resp = client.unifiedRefund(refundReqDTO);
 | 
			
		||||
        // 断言
 | 
			
		||||
        assertEquals(PayRefundStatusRespEnum.SUCCESS.getStatus(), resp.getStatus());
 | 
			
		||||
        assertNull(resp.getChannelRefundNo());
 | 
			
		||||
        assertEquals(LocalDateTimeUtil.of(refundTime), resp.getSuccessTime());
 | 
			
		||||
        assertEquals(outRefundNo, resp.getOutRefundNo());
 | 
			
		||||
        assertSame(response, resp.getRawData());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @DisplayName("支付包扫描退款,渠道返回失败")
 | 
			
		||||
    public void test_unified_refund_channel_failed() throws AlipayApiException {
 | 
			
		||||
        // 准备返回对象
 | 
			
		||||
        String notifyUrl = randomURL();
 | 
			
		||||
        String subCode = randomString();
 | 
			
		||||
        String subMsg = randomString();
 | 
			
		||||
        AlipayTradeRefundResponse response = randomPojo(AlipayTradeRefundResponse.class, o -> {
 | 
			
		||||
            o.setSubCode(subCode);
 | 
			
		||||
            o.setSubMsg(subMsg);
 | 
			
		||||
        });
 | 
			
		||||
        // mock
 | 
			
		||||
        when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> {
 | 
			
		||||
            assertInstanceOf(AlipayTradeRefundModel.class, request.getBizModel());
 | 
			
		||||
            return true;
 | 
			
		||||
        }))).thenReturn(response);
 | 
			
		||||
        // 准备请求参数
 | 
			
		||||
        String outRefundNo = randomString();
 | 
			
		||||
        String outTradeNo = randomString();
 | 
			
		||||
        PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
 | 
			
		||||
            o.setOutRefundNo(outRefundNo);
 | 
			
		||||
            o.setOutTradeNo(outTradeNo);
 | 
			
		||||
            o.setNotifyUrl(notifyUrl);
 | 
			
		||||
        });
 | 
			
		||||
        PayRefundRespDTO resp = client.unifiedRefund(refundReqDTO);
 | 
			
		||||
        // 断言
 | 
			
		||||
        assertEquals(PayRefundStatusRespEnum.FAILURE.getStatus(), resp.getStatus());
 | 
			
		||||
        assertNull(resp.getChannelRefundNo());
 | 
			
		||||
        assertEquals(subCode, resp.getChannelErrorCode());
 | 
			
		||||
        assertEquals(subMsg, resp.getChannelErrorMsg());
 | 
			
		||||
        assertNull(resp.getSuccessTime());
 | 
			
		||||
        assertEquals(outRefundNo, resp.getOutRefundNo());
 | 
			
		||||
        assertSame(response, resp.getRawData());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @DisplayName("支付包扫描退款,参数校验不通过")
 | 
			
		||||
    public void test_unified_refund_param_validate() {
 | 
			
		||||
        // 准备请求参数
 | 
			
		||||
        String notifyUrl = randomURL();
 | 
			
		||||
        PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
 | 
			
		||||
            o.setOutTradeNo("");
 | 
			
		||||
            o.setNotifyUrl(notifyUrl);
 | 
			
		||||
        });
 | 
			
		||||
        // 断言
 | 
			
		||||
        assertThrows(ConstraintViolationException.class, () -> client.unifiedRefund(refundReqDTO));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @DisplayName("支付包扫描退款,抛出业务异常")
 | 
			
		||||
    public void test_unified_refund_throw_service_exception() throws AlipayApiException {
 | 
			
		||||
        // mock
 | 
			
		||||
        when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> true)))
 | 
			
		||||
                .thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR));
 | 
			
		||||
        // 准备请求参数
 | 
			
		||||
        String notifyUrl = randomURL();
 | 
			
		||||
        PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
 | 
			
		||||
            o.setNotifyUrl(notifyUrl);
 | 
			
		||||
        });
 | 
			
		||||
        // 断言
 | 
			
		||||
        assertThrows(ServiceException.class, () -> client.unifiedRefund(refundReqDTO));
 | 
			
		||||
    }
 | 
			
		||||
    @Test
 | 
			
		||||
    @DisplayName("支付包扫描退款,抛出系统异常")
 | 
			
		||||
    public void test_unified_refund_throw_pay_exception() throws AlipayApiException {
 | 
			
		||||
        // mock
 | 
			
		||||
        when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> true)))
 | 
			
		||||
                .thenThrow(new RuntimeException("系统异常"));
 | 
			
		||||
        // 准备请求参数
 | 
			
		||||
        String notifyUrl = randomURL();
 | 
			
		||||
        PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> {
 | 
			
		||||
            o.setNotifyUrl(notifyUrl);
 | 
			
		||||
        });
 | 
			
		||||
        // 断言
 | 
			
		||||
        assertThrows(PayException.class, () -> client.unifiedRefund(refundReqDTO));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,16 +7,14 @@ import org.junit.jupiter.api.BeforeEach;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
import org.mockito.InjectMocks;
 | 
			
		||||
import org.mockito.Mock;
 | 
			
		||||
import org.mockito.Mockito;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import static cn.iocoder.yudao.module.promotion.enums.decorate.DecorateComponentEnum.ROLLING_NEWS;
 | 
			
		||||
import static cn.iocoder.yudao.module.promotion.enums.decorate.DecoratePageEnum.INDEX;
 | 
			
		||||
import static org.mockito.ArgumentMatchers.eq;
 | 
			
		||||
 | 
			
		||||
// TODO @芋艿:后续 review 下
 | 
			
		||||
// TODO 待完成  @芋艿:后续 review 下
 | 
			
		||||
/**
 | 
			
		||||
 * @author jason
 | 
			
		||||
 */
 | 
			
		||||
@ -41,6 +39,6 @@ public class DecorateComponentServiceImplTest extends BaseMockitoUnitTest {
 | 
			
		||||
                .setCode(ROLLING_NEWS.getCode()).setId(1L);
 | 
			
		||||
        list.add(decorateDO);
 | 
			
		||||
        //mock 方法
 | 
			
		||||
        Mockito.when(decorateComponentMapper.selectListByPageAndStatus(eq(1))).thenReturn(list);
 | 
			
		||||
        //Mockito.when(decorateComponentMapper.selectListByPageAndStatus(eq(1))).thenReturn(list);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user