by gateway:

1. 完善部分 refund 单元测试
This commit is contained in:
zhijiantianya@gmail.com
2023-07-21 22:02:39 +08:00
parent da529851bd
commit e27ec2fd50
4 changed files with 492 additions and 116 deletions

View File

@@ -30,7 +30,6 @@ import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.MockedStatic;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
@@ -44,8 +43,7 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -85,6 +83,51 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
when(properties.getOrderNotifyUrl()).thenReturn("http://127.0.0.1");
}
@Test
public void testGetOrder_id() {
// mock 数据PayOrderDO
PayOrderDO order = randomPojo(PayOrderDO.class);
orderMapper.insert(order);
// 准备参数
Long id = order.getId();
// 调用
PayOrderDO dbOrder = orderService.getOrder(id);
// 断言
assertPojoEquals(dbOrder, order);
}
@Test
public void testGetOrder_appIdAndMerchantOrderId() {
// mock 数据PayOrderDO
PayOrderDO order = randomPojo(PayOrderDO.class);
orderMapper.insert(order);
// 准备参数
Long appId = order.getAppId();
String merchantOrderId = order.getMerchantOrderId();
// 调用
PayOrderDO dbOrder = orderService.getOrder(appId, merchantOrderId);
// 断言
assertPojoEquals(dbOrder, order);
}
@Test
public void testGetOrderCountByAppId() {
// mock 数据PayOrderDO
PayOrderDO order01 = randomPojo(PayOrderDO.class);
orderMapper.insert(order01);
PayOrderDO order02 = randomPojo(PayOrderDO.class);
orderMapper.insert(order02);
// 准备参数
Long appId = order01.getAppId();
// 调用
Long count = orderService.getOrderCountByAppId(appId);
// 断言
assertEquals(count, 1L);
}
@Test
public void testGetOrderPage() {
// mock 数据
@@ -350,7 +393,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
// mock 方法client
PayClient client = mock(PayClient.class);
when(payClientFactory.getPayClient(eq(10L))).thenReturn(client);
// mock 方法()
// mock 方法(支付渠道的调用
PayOrderRespDTO unifiedOrderResp = randomPojo(PayOrderRespDTO.class, o -> o.setChannelErrorCode(null).setChannelErrorMsg(null)
.setDisplayMode(PayOrderDisplayModeEnum.URL.getMode()).setDisplayContent("tudou"));
when(client.unifiedOrder(argThat(payOrderUnifiedReqDTO -> {
@@ -553,14 +596,193 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest {
assertPojoEquals(order, orderMapper.selectOne(null),
"updateTime", "updater");
// 断言,调用
verify(notifyService).createPayNotifyTask(argThat(new ArgumentMatcher<PayNotifyTaskCreateReqDTO>() {
@Override
public boolean matches(PayNotifyTaskCreateReqDTO reqDTO) {
assertEquals(reqDTO.getType(), PayNotifyTypeEnum.ORDER.getType());
assertEquals(reqDTO.getDataId(), orderExtension.getOrderId());
return true;
}
verify(notifyService).createPayNotifyTask(argThat(reqDTO -> {
assertEquals(reqDTO.getType(), PayNotifyTypeEnum.ORDER.getType());
assertEquals(reqDTO.getDataId(), orderExtension.getOrderId());
return true;
}));
}
@Test
public void testNotifyOrderClosed_orderExtension_notFound() {
// 准备参数
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L));
PayOrderRespDTO notify = randomPojo(PayOrderRespDTO.class,
o -> o.setStatus(PayOrderStatusRespEnum.CLOSED.getStatus()));
// 调用,并断言异常
assertServiceException(() -> orderService.notifyOrder(channel, notify),
ORDER_EXTENSION_NOT_FOUND);
}
@Test
public void testNotifyOrderClosed_orderExtension_closed() {
// mock 数据PayOrderExtensionDO
PayOrderExtensionDO orderExtension = randomPojo(PayOrderExtensionDO.class,
o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus())
.setNo("P110"));
orderExtensionMapper.insert(orderExtension);
// 准备参数
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L));
PayOrderRespDTO notify = randomPojo(PayOrderRespDTO.class,
o -> o.setStatus(PayOrderStatusRespEnum.CLOSED.getStatus())
.setOutTradeNo("P110"));
// 调用,并断言
orderService.notifyOrder(channel, notify);
// 断言 PayOrderExtensionDO :数据未更新,因为它是 CLOSED
assertPojoEquals(orderExtension, orderExtensionMapper.selectOne(null));
}
@Test
public void testNotifyOrderClosed_orderExtension_paid() {
// mock 数据PayOrderExtensionDO
PayOrderExtensionDO orderExtension = randomPojo(PayOrderExtensionDO.class,
o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus())
.setNo("P110"));
orderExtensionMapper.insert(orderExtension);
// 准备参数
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L));
PayOrderRespDTO notify = randomPojo(PayOrderRespDTO.class,
o -> o.setStatus(PayOrderStatusRespEnum.CLOSED.getStatus())
.setOutTradeNo("P110"));
// 调用,并断言
orderService.notifyOrder(channel, notify);
// 断言 PayOrderExtensionDO :数据未更新,因为它是 SUCCESS
assertPojoEquals(orderExtension, orderExtensionMapper.selectOne(null));
}
@Test
public void testNotifyOrderClosed_orderExtension_refund() {
// mock 数据PayOrderExtensionDO
PayOrderExtensionDO orderExtension = randomPojo(PayOrderExtensionDO.class,
o -> o.setStatus(PayOrderStatusEnum.REFUND.getStatus())
.setNo("P110"));
orderExtensionMapper.insert(orderExtension);
// 准备参数
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L));
PayOrderRespDTO notify = randomPojo(PayOrderRespDTO.class,
o -> o.setStatus(PayOrderStatusRespEnum.CLOSED.getStatus())
.setOutTradeNo("P110"));
// 调用,并断言异常
assertServiceException(() -> orderService.notifyOrder(channel, notify),
ORDER_EXTENSION_STATUS_IS_NOT_WAITING);
}
@Test
public void testNotifyOrderClosed_orderExtension_waiting() {
// mock 数据PayOrderExtensionDO
PayOrderExtensionDO orderExtension = randomPojo(PayOrderExtensionDO.class,
o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus())
.setNo("P110"));
orderExtensionMapper.insert(orderExtension);
// 准备参数
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L));
PayOrderRespDTO notify = randomPojo(PayOrderRespDTO.class,
o -> o.setStatus(PayOrderStatusRespEnum.CLOSED.getStatus())
.setOutTradeNo("P110"));
// 调用
orderService.notifyOrder(channel, notify);
// 断言 PayOrderExtensionDO
orderExtension.setStatus(PayOrderStatusEnum.CLOSED.getStatus()).setChannelNotifyData(toJsonString(notify))
.setChannelErrorCode(notify.getChannelErrorCode()).setChannelErrorMsg(notify.getChannelErrorMsg());
assertPojoEquals(orderExtension, orderExtensionMapper.selectOne(null),
"updateTime", "updater");
}
@Test
public void testUpdateOrderRefundPrice_notFound() {
// 准备参数
Long id = randomLongId();
Integer incrRefundPrice = randomInteger();
// 调用,并断言异常
assertServiceException(() -> orderService.updateOrderRefundPrice(id, incrRefundPrice),
ORDER_NOT_FOUND);
}
@Test
public void testUpdateOrderRefundPrice_waiting() {
testUpdateOrderRefundPrice_waitingOrClosed(PayOrderStatusEnum.WAITING.getStatus());
}
@Test
public void testUpdateOrderRefundPrice_closed() {
testUpdateOrderRefundPrice_waitingOrClosed(PayOrderStatusEnum.CLOSED.getStatus());
}
private void testUpdateOrderRefundPrice_waitingOrClosed(Integer status) {
// mock 数据PayOrderDO
PayOrderDO order = randomPojo(PayOrderDO.class,
o -> o.setStatus(status));
orderMapper.insert(order);
// 准备参数
Long id = order.getId();
Integer incrRefundPrice = randomInteger();
// 调用,并断言异常
assertServiceException(() -> orderService.updateOrderRefundPrice(id, incrRefundPrice),
ORDER_REFUND_FAIL_STATUS_ERROR);
}
@Test
public void testUpdateOrderRefundPrice_priceExceed() {
// mock 数据PayOrderDO
PayOrderDO order = randomPojo(PayOrderDO.class,
o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus())
.setRefundPrice(1).setPrice(10));
orderMapper.insert(order);
// 准备参数
Long id = order.getId();
Integer incrRefundPrice = 10;
// 调用,并断言异常
assertServiceException(() -> orderService.updateOrderRefundPrice(id, incrRefundPrice),
REFUND_PRICE_EXCEED);
}
@Test
public void testUpdateOrderRefundPrice_refund() {
testUpdateOrderRefundPrice_refundOrSuccess(PayOrderStatusEnum.REFUND.getStatus());
}
@Test
public void testUpdateOrderRefundPrice_success() {
testUpdateOrderRefundPrice_refundOrSuccess(PayOrderStatusEnum.SUCCESS.getStatus());
}
private void testUpdateOrderRefundPrice_refundOrSuccess(Integer status) {
// mock 数据PayOrderDO
PayOrderDO order = randomPojo(PayOrderDO.class,
o -> o.setStatus(status).setRefundPrice(1).setPrice(10));
orderMapper.insert(order);
// 准备参数
Long id = order.getId();
Integer incrRefundPrice = 8;
// 调用
orderService.updateOrderRefundPrice(id, incrRefundPrice);
// 断言
order.setRefundPrice(9).setStatus(PayOrderStatusEnum.REFUND.getStatus());
assertPojoEquals(order, orderMapper.selectOne(null),
"updateTime", "updater");
}
@Test
public void testGetOrderExtension() {
// mock 数据PayOrderExtensionDO
PayOrderExtensionDO orderExtension = randomPojo(PayOrderExtensionDO.class);
orderExtensionMapper.insert(orderExtension);
// 准备参数
Long id = orderExtension.getId();
// 调用
PayOrderExtensionDO dbOrderExtension = orderService.getOrderExtension(id);
// 断言
assertPojoEquals(dbOrderExtension, orderExtension);
}
}

View File

@@ -1,14 +1,19 @@
package cn.iocoder.yudao.module.pay.service.refund;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.pay.core.client.PayClient;
import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExportReqVO;
import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExportReqVO;
import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundPageReqVO;
import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper;
import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO;
import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum;
import cn.iocoder.yudao.module.pay.framework.pay.config.PayProperties;
@@ -24,12 +29,25 @@ import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@Import(PayRefundServiceImpl.class)
/**
* {@link PayRefundServiceImpl} 的单元测试类
*
* @author 芋艿
*/
@Import({PayRefundServiceImpl.class, PayNoRedisDAO.class})
public class PayRefundServiceTest extends BaseDbAndRedisUnitTest {
@Resource
@@ -56,45 +74,41 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest {
// mock 数据
PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到
o.setAppId(1L);
o.setChannelId(1L);
o.setChannelCode(PayChannelEnum.WX_PUB.getCode());
o.setOrderId(1L);
o.setNo("OT0000001");
o.setMerchantOrderId("MOT0000001");
o.setMerchantRefundId("MRF0000001");
o.setNotifyUrl("https://www.cancanzi.com");
o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
o.setPayPrice(100);
o.setRefundPrice(500);
o.setReason("就是想退款了,你有意见吗");
o.setUserIp("127.0.0.1");
o.setChannelOrderNo("CH0000001");
o.setChannelRefundNo("CHR0000001");
o.setChannelErrorCode("");
o.setChannelErrorMsg("");
o.setSuccessTime(LocalDateTime.of(2021, 1, 1, 10, 10, 15));
o.setCreateTime(LocalDateTime.of(2021, 1, 1, 10, 10, 10));
o.setUpdateTime(LocalDateTime.of(2021, 1, 1, 10, 10, 35));
o.setCreateTime(buildTime(2021, 1, 10));
});
refundMapper.insert(dbRefund);
// 测试 appId 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setAppId(2L)));
// 测试 channelCode 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
// 测试 merchantRefundNo 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundId("MRF1111112")));
// 测试 merchantOrderId 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantOrderId(randomString())));
// 测试 merchantRefundId 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundId(randomString())));
// 测试 channelOrderNo 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelOrderNo(randomString())));
// 测试 channelRefundNo 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelRefundNo(randomString())));
// 测试 status 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus())));
// 测试 createTime 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o ->
o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10))));
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setCreateTime(buildTime(2021, 1, 1))));
// 准备参数
PayRefundPageReqVO reqVO = new PayRefundPageReqVO();
reqVO.setAppId(1L);
reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
reqVO.setMerchantOrderId("MOT0000001");
reqVO.setMerchantRefundId("MRF0000001");
reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
reqVO.setCreateTime((new LocalDateTime[]{LocalDateTime.of(2021, 1, 1, 10, 10, 10), LocalDateTime.of(2021, 1, 1, 10, 10, 12)}));
reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
reqVO.setChannelOrderNo("CH0000001");
reqVO.setChannelRefundNo("CHR0000001");
reqVO.setCreateTime(buildBetweenTime(2021, 1, 9, 2021, 1, 11));
// 调用
PageResult<PayRefundDO> pageResult = refundService.getRefundPage(reqVO);
@@ -109,45 +123,41 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest {
// mock 数据
PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到
o.setAppId(1L);
o.setChannelId(1L);
o.setChannelCode(PayChannelEnum.WX_PUB.getCode());
o.setOrderId(1L);
o.setNo("OT0000001");
o.setMerchantOrderId("MOT0000001");
o.setMerchantRefundId("MRF0000001");
o.setNotifyUrl("https://www.cancanzi.com");
o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
o.setPayPrice(100);
o.setRefundPrice(500);
o.setReason("就是想退款了,你有意见吗");
o.setUserIp("127.0.0.1");
o.setChannelOrderNo("CH0000001");
o.setChannelRefundNo("CHR0000001");
o.setChannelErrorCode("");
o.setChannelErrorMsg("");
o.setSuccessTime(LocalDateTime.of(2021, 1, 1, 10, 10, 15));
o.setCreateTime(LocalDateTime.of(2021, 1, 1, 10, 10, 10));
o.setUpdateTime(LocalDateTime.of(2021, 1, 1, 10, 10, 35));
o.setCreateTime(buildTime(2021, 1, 10));
});
refundMapper.insert(dbRefund);
// 测试 appId 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setAppId(2L)));
// 测试 channelCode 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
// 测试 merchantRefundNo 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundId("MRF1111112")));
// 测试 merchantOrderId 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantOrderId(randomString())));
// 测试 merchantRefundId 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundId(randomString())));
// 测试 channelOrderNo 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelOrderNo(randomString())));
// 测试 channelRefundNo 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelRefundNo(randomString())));
// 测试 status 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus())));
// 测试 createTime 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o ->
o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10))));
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setCreateTime(buildTime(2021, 1, 1))));
// 准备参数
PayRefundExportReqVO reqVO = new PayRefundExportReqVO();
reqVO.setAppId(1L);
reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
reqVO.setCreateTime((new LocalDateTime[]{LocalDateTime.of(2021, 1, 1, 10, 10, 10), LocalDateTime.of(2021, 1, 1, 10, 10, 12)}));
reqVO.setMerchantOrderId("MOT0000001");
reqVO.setMerchantRefundId("MRF0000001");
reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
reqVO.setChannelOrderNo("CH0000001");
reqVO.setChannelRefundNo("CHR0000001");
reqVO.setCreateTime(buildBetweenTime(2021, 1, 9, 2021, 1, 11));
// 调用
List<PayRefundDO> list = refundService.getRefundList(reqVO);
@@ -156,4 +166,151 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest {
assertPojoEquals(dbRefund, list.get(0));
}
@Test
public void testCreateRefund_orderNotFound() {
PayRefundCreateReqDTO reqDTO = randomPojo(PayRefundCreateReqDTO.class,
o -> o.setAppId(1L));
// mock 方法app
PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L));
when(appService.validPayApp(eq(1L))).thenReturn(app);
// 调用,并断言异常
assertServiceException(() -> refundService.createPayRefund(reqDTO),
ORDER_NOT_FOUND);
}
@Test
public void testCreateRefund_orderWaiting() {
testCreateRefund_orderWaitingOrClosed(PayOrderStatusEnum.WAITING.getStatus());
}
@Test
public void testCreateRefund_orderClosed() {
testCreateRefund_orderWaitingOrClosed(PayOrderStatusEnum.CLOSED.getStatus());
}
private void testCreateRefund_orderWaitingOrClosed(Integer status) {
// 准备参数
PayRefundCreateReqDTO reqDTO = randomPojo(PayRefundCreateReqDTO.class,
o -> o.setAppId(1L).setMerchantOrderId("100"));
// mock 方法app
PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L));
when(appService.validPayApp(eq(1L))).thenReturn(app);
// mock 数据order
PayOrderDO order = randomPojo(PayOrderDO.class, o -> o.setStatus(status));
when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order);
// 调用,并断言异常
assertServiceException(() -> refundService.createPayRefund(reqDTO),
ORDER_REFUND_FAIL_STATUS_ERROR);
}
@Test
public void testCreateRefund_refundPriceExceed() {
// 准备参数
PayRefundCreateReqDTO reqDTO = randomPojo(PayRefundCreateReqDTO.class,
o -> o.setAppId(1L).setMerchantOrderId("100").setPrice(10));
// mock 方法app
PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L));
when(appService.validPayApp(eq(1L))).thenReturn(app);
// mock 数据order
PayOrderDO order = randomPojo(PayOrderDO.class, o ->
o.setStatus(PayOrderStatusEnum.REFUND.getStatus())
.setPrice(10).setRefundPrice(1));
when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order);
// 调用,并断言异常
assertServiceException(() -> refundService.createPayRefund(reqDTO),
REFUND_PRICE_EXCEED);
}
@Test
public void testCreateRefund_orderHasRefunding() {
// 准备参数
PayRefundCreateReqDTO reqDTO = randomPojo(PayRefundCreateReqDTO.class,
o -> o.setAppId(1L).setMerchantOrderId("100").setPrice(10));
// mock 方法app
PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L));
when(appService.validPayApp(eq(1L))).thenReturn(app);
// mock 数据order
PayOrderDO order = randomPojo(PayOrderDO.class, o ->
o.setStatus(PayOrderStatusEnum.REFUND.getStatus())
.setPrice(10).setRefundPrice(1));
when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order);
// mock 数据refund 在退款中)
PayRefundDO refund = randomPojo(PayRefundDO.class, o ->
o.setOrderId(order.getId()).setStatus(PayOrderStatusEnum.WAITING.getStatus()));
refundMapper.insert(refund);
// 调用,并断言异常
assertServiceException(() -> refundService.createPayRefund(reqDTO),
REFUND_PRICE_EXCEED);
}
@Test
public void testCreateRefund_channelNotFound() {
// 准备参数
PayRefundCreateReqDTO reqDTO = randomPojo(PayRefundCreateReqDTO.class,
o -> o.setAppId(1L).setMerchantOrderId("100").setPrice(9));
// mock 方法app
PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L));
when(appService.validPayApp(eq(1L))).thenReturn(app);
// mock 数据order
PayOrderDO order = randomPojo(PayOrderDO.class, o ->
o.setStatus(PayOrderStatusEnum.REFUND.getStatus())
.setPrice(10).setRefundPrice(1)
.setChannelId(1L).setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()));
when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order);
// mock 方法channel
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L)
.setCode(PayChannelEnum.ALIPAY_APP.getCode()));
when(channelService.validPayChannel(eq(1L))).thenReturn(channel);
// 调用,并断言异常
assertServiceException(() -> refundService.createPayRefund(reqDTO),
CHANNEL_NOT_FOUND);
}
@Test
public void testCreateRefund_refundExists() {
// 准备参数
PayRefundCreateReqDTO reqDTO = randomPojo(PayRefundCreateReqDTO.class,
o -> o.setAppId(1L).setMerchantOrderId("100").setPrice(9)
.setReason("测试退款"));
// mock 方法app
PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L));
when(appService.validPayApp(eq(1L))).thenReturn(app);
// mock 数据order
PayOrderDO order = randomPojo(PayOrderDO.class, o ->
o.setStatus(PayOrderStatusEnum.REFUND.getStatus())
.setPrice(10).setRefundPrice(1)
.setChannelId(1L).setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()));
when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order);
// mock 方法channel
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L)
.setCode(PayChannelEnum.ALIPAY_APP.getCode()));
when(channelService.validPayChannel(eq(1L))).thenReturn(channel);
// mock 方法client
PayClient client = mock(PayClient.class);
when(payClientFactory.getPayClient(eq(10L))).thenReturn(client);
// mock 数据refund 已存在)
PayRefundDO refund = randomPojo(PayRefundDO.class, o ->
o.setOrderId(order.getId()).setStatus(PayOrderStatusEnum.WAITING.getStatus()));
refundMapper.insert(refund);
// 调用,并断言异常
assertServiceException(() -> refundService.createPayRefund(reqDTO),
REFUND_EXISTS);
}
@Test
public void testCreateRefund_invokeException() {
}
@Test
public void testCreateRefund_invokeSuccess() {
}
}

View File

@@ -82,29 +82,25 @@ CREATE TABLE IF NOT EXISTS `pay_order_extension` (
CREATE TABLE IF NOT EXISTS `pay_refund` (
"id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
`no` varchar(64) NOT NULL,
`app_id` bigint(20) NOT NULL,
`channel_id` bigint(20) NOT NULL,
`channel_code` varchar(32) NOT NULL,
`order_id` bigint(20) NOT NULL,
`trade_no` varchar(64) NOT NULL,
`merchant_order_id` varchar(64) NOT NULL,
`merchant_refund_no` varchar(64) NOT NULL,
`merchant_refund_id` varchar(64) NOT NULL,
`notify_url` varchar(1024) NOT NULL,
`notify_status` tinyint(4) NOT NULL,
`status` tinyint(4) NOT NULL,
`type` tinyint(4) NOT NULL,
`pay_amount` bigint(20) NOT NULL,
`refund_amount` bigint(20) NOT NULL,
`pay_price` bigint(20) NOT NULL,
`refund_price` bigint(20) NOT NULL,
`reason` varchar(256) NOT NULL,
`user_ip` varchar(50) NULL DEFAULT NULL,
`channel_order_no` varchar(64) NOT NULL,
`channel_refund_no` varchar(64) NULL DEFAULT NULL,
`success_time` datetime(0) NULL DEFAULT NULL,
`channel_error_code` varchar(128) NULL DEFAULT NULL,
`channel_error_msg` varchar(256) NULL DEFAULT NULL,
`channel_extras` varchar(1024) NULL DEFAULT NULL,
`expire_time` datetime(0) NULL DEFAULT NULL,
`success_time` datetime(0) NULL DEFAULT NULL,
`notify_time` datetime(0) NULL DEFAULT NULL,
`channel_notify_data` varchar(1024) NULL,
`creator` varchar(64) NULL DEFAULT '',
`create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updater` varchar(64) NULL DEFAULT '',