mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 23:31:52 +08:00
mall + pay:
1. 完善 PayRefundServiceTest 的单元测试
This commit is contained in:
parent
ebeb14be2f
commit
6aea461e8d
@ -212,7 +212,7 @@ public class PayRefundServiceImpl implements PayRefundService {
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyRefundSuccess(PayChannelDO channel, PayRefundRespDTO notify) {
|
||||
private void notifyRefundSuccess(PayChannelDO channel, PayRefundRespDTO notify) {
|
||||
// 1.1 查询 PayRefundDO
|
||||
PayRefundDO refund = refundMapper.selectByAppIdAndNo(
|
||||
channel.getAppId(), notify.getOutRefundNo());
|
||||
@ -246,8 +246,7 @@ public class PayRefundServiceImpl implements PayRefundService {
|
||||
.type(PayNotifyTypeEnum.REFUND.getType()).dataId(refund.getId()).build());
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void notifyRefundFailure(PayChannelDO channel, PayRefundRespDTO notify) {
|
||||
private void notifyRefundFailure(PayChannelDO channel, PayRefundRespDTO notify) {
|
||||
// 1.1 查询 PayRefundDO
|
||||
PayRefundDO refund = refundMapper.selectByAppIdAndNo(
|
||||
channel.getAppId(), notify.getOutRefundNo());
|
||||
|
@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
|
||||
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.enums.channel.PayChannelEnum;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExportReqVO;
|
||||
@ -17,12 +18,14 @@ 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.notify.PayNotifyTypeEnum;
|
||||
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;
|
||||
import cn.iocoder.yudao.module.pay.service.app.PayAppService;
|
||||
import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
|
||||
import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
|
||||
import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -35,6 +38,7 @@ 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.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;
|
||||
@ -42,8 +46,7 @@ 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.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
@ -439,4 +442,263 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyRefund() {
|
||||
PayRefundServiceImpl payRefundServiceImpl = mock(PayRefundServiceImpl.class);
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PayRefundServiceImpl.class)))
|
||||
.thenReturn(payRefundServiceImpl);
|
||||
|
||||
// 准备参数
|
||||
Long channelId = 10L;
|
||||
PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class);
|
||||
// mock 方法(channel)
|
||||
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L));
|
||||
when(channelService.validPayChannel(eq(10L))).thenReturn(channel);
|
||||
|
||||
// 调用
|
||||
refundService.notifyRefund(channelId, refundRespDTO);
|
||||
// 断言
|
||||
verify(payRefundServiceImpl).notifyRefund(same(channel), same(refundRespDTO));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyRefundSuccess_notFound() {
|
||||
// 准备参数
|
||||
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L).setAppId(1L));
|
||||
PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class,
|
||||
o -> o.setStatus(PayRefundStatusRespEnum.SUCCESS.getStatus()).setOutRefundNo("R100"));
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> refundService.notifyRefund(channel, refundRespDTO),
|
||||
REFUND_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyRefundSuccess_isSuccess() {
|
||||
// 准备参数
|
||||
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L).setAppId(1L));
|
||||
PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class,
|
||||
o -> o.setStatus(PayRefundStatusRespEnum.SUCCESS.getStatus()).setOutRefundNo("R100"));
|
||||
// mock 数据(refund + 已支付)
|
||||
PayRefundDO refund = randomPojo(PayRefundDO.class, o -> o.setAppId(1L).setNo("R100")
|
||||
.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()));
|
||||
refundMapper.insert(refund);
|
||||
|
||||
// 调用
|
||||
refundService.notifyRefund(channel, refundRespDTO);
|
||||
// 断言,refund 没有更新,因为已经退款成功
|
||||
assertPojoEquals(refund, refundMapper.selectById(refund.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyRefundSuccess_failure() {
|
||||
// 准备参数
|
||||
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L).setAppId(1L));
|
||||
PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class,
|
||||
o -> o.setStatus(PayRefundStatusRespEnum.SUCCESS.getStatus()).setOutRefundNo("R100"));
|
||||
// mock 数据(refund + 已支付)
|
||||
PayRefundDO refund = randomPojo(PayRefundDO.class, o -> o.setAppId(1L).setNo("R100")
|
||||
.setStatus(PayRefundStatusEnum.FAILURE.getStatus()));
|
||||
refundMapper.insert(refund);
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> refundService.notifyRefund(channel, refundRespDTO),
|
||||
REFUND_STATUS_IS_NOT_WAITING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyRefundSuccess_updateOrderException() {
|
||||
// 准备参数
|
||||
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L).setAppId(1L));
|
||||
PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class,
|
||||
o -> o.setStatus(PayRefundStatusRespEnum.SUCCESS.getStatus()).setOutRefundNo("R100"));
|
||||
// mock 数据(refund + 已支付)
|
||||
PayRefundDO refund = randomPojo(PayRefundDO.class, o -> o.setAppId(1L).setNo("R100")
|
||||
.setStatus(PayRefundStatusEnum.WAITING.getStatus())
|
||||
.setOrderId(100L).setRefundPrice(23));
|
||||
refundMapper.insert(refund);
|
||||
// mock 方法(order + 更新异常)
|
||||
doThrow(new RuntimeException()).when(orderService)
|
||||
.updateOrderRefundPrice(eq(100L), eq(23));
|
||||
|
||||
// 调用,并断言异常
|
||||
assertThrows(RuntimeException.class, () -> refundService.notifyRefund(channel, refundRespDTO));
|
||||
// 断言,refund 没有更新,因为事务回滚了
|
||||
assertPojoEquals(refund, refundMapper.selectById(refund.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyRefundSuccess_success() {
|
||||
// 准备参数
|
||||
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L).setAppId(1L));
|
||||
PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class,
|
||||
o -> o.setStatus(PayRefundStatusRespEnum.SUCCESS.getStatus()).setOutRefundNo("R100"));
|
||||
// mock 数据(refund + 已支付)
|
||||
PayRefundDO refund = randomPojo(PayRefundDO.class, o -> o.setAppId(1L).setNo("R100")
|
||||
.setStatus(PayRefundStatusEnum.WAITING.getStatus())
|
||||
.setOrderId(100L).setRefundPrice(23));
|
||||
refundMapper.insert(refund);
|
||||
|
||||
// 调用
|
||||
refundService.notifyRefund(channel, refundRespDTO);
|
||||
// 断言,refund
|
||||
refund.setSuccessTime(refundRespDTO.getSuccessTime())
|
||||
.setChannelRefundNo(refundRespDTO.getChannelRefundNo())
|
||||
.setStatus(PayRefundStatusEnum.SUCCESS.getStatus())
|
||||
.setChannelNotifyData(toJsonString(refundRespDTO));
|
||||
assertPojoEquals(refund, refundMapper.selectById(refund.getId()),
|
||||
"updateTime", "updater");
|
||||
// 断言,调用
|
||||
verify(orderService).updateOrderRefundPrice(eq(100L), eq(23));
|
||||
verify(notifyService).createPayNotifyTask(eq(PayNotifyTaskCreateReqDTO.builder()
|
||||
.type(PayNotifyTypeEnum.REFUND.getType()).dataId(refund.getId()).build()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyRefundFailure_notFound() {
|
||||
// 准备参数
|
||||
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L).setAppId(1L));
|
||||
PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class,
|
||||
o -> o.setStatus(PayRefundStatusRespEnum.FAILURE.getStatus()).setOutRefundNo("R100"));
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> refundService.notifyRefund(channel, refundRespDTO),
|
||||
REFUND_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyRefundFailure_isFailure() {
|
||||
// 准备参数
|
||||
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L).setAppId(1L));
|
||||
PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class,
|
||||
o -> o.setStatus(PayRefundStatusRespEnum.FAILURE.getStatus()).setOutRefundNo("R100"));
|
||||
// mock 数据(refund + 退款失败)
|
||||
PayRefundDO refund = randomPojo(PayRefundDO.class, o -> o.setAppId(1L).setNo("R100")
|
||||
.setStatus(PayRefundStatusEnum.FAILURE.getStatus()));
|
||||
refundMapper.insert(refund);
|
||||
|
||||
// 调用
|
||||
refundService.notifyRefund(channel, refundRespDTO);
|
||||
// 断言,refund 没有更新,因为已经退款失败
|
||||
assertPojoEquals(refund, refundMapper.selectById(refund.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyRefundFailure_isSuccess() {
|
||||
// 准备参数
|
||||
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L).setAppId(1L));
|
||||
PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class,
|
||||
o -> o.setStatus(PayRefundStatusRespEnum.FAILURE.getStatus()).setOutRefundNo("R100"));
|
||||
// mock 数据(refund + 已支付)
|
||||
PayRefundDO refund = randomPojo(PayRefundDO.class, o -> o.setAppId(1L).setNo("R100")
|
||||
.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()));
|
||||
refundMapper.insert(refund);
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> refundService.notifyRefund(channel, refundRespDTO),
|
||||
REFUND_STATUS_IS_NOT_WAITING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyRefundFailure_success() {
|
||||
// 准备参数
|
||||
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L).setAppId(1L));
|
||||
PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class,
|
||||
o -> o.setStatus(PayRefundStatusRespEnum.FAILURE.getStatus()).setOutRefundNo("R100"));
|
||||
// mock 数据(refund + 已支付)
|
||||
PayRefundDO refund = randomPojo(PayRefundDO.class, o -> o.setAppId(1L).setNo("R100")
|
||||
.setStatus(PayRefundStatusEnum.WAITING.getStatus())
|
||||
.setOrderId(100L).setRefundPrice(23));
|
||||
refundMapper.insert(refund);
|
||||
|
||||
// 调用
|
||||
refundService.notifyRefund(channel, refundRespDTO);
|
||||
// 断言,refund
|
||||
refund.setChannelRefundNo(refundRespDTO.getChannelRefundNo())
|
||||
.setStatus(PayRefundStatusEnum.FAILURE.getStatus())
|
||||
.setChannelNotifyData(toJsonString(refundRespDTO))
|
||||
.setChannelErrorCode(refundRespDTO.getChannelErrorCode())
|
||||
.setChannelErrorMsg(refundRespDTO.getChannelErrorMsg());
|
||||
assertPojoEquals(refund, refundMapper.selectById(refund.getId()),
|
||||
"updateTime", "updater");
|
||||
// 断言,调用
|
||||
verify(notifyService).createPayNotifyTask(eq(PayNotifyTaskCreateReqDTO.builder()
|
||||
.type(PayNotifyTypeEnum.REFUND.getType()).dataId(refund.getId()).build()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyncRefund_notFound() {
|
||||
// 准备参数
|
||||
PayRefundDO refund = randomPojo(PayRefundDO.class, o -> o.setAppId(1L)
|
||||
.setStatus(PayRefundStatusEnum.WAITING.getStatus()));
|
||||
refundMapper.insert(refund);
|
||||
|
||||
// 调用
|
||||
int count = refundService.syncRefund();
|
||||
// 断言
|
||||
assertEquals(count, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyncRefund_waiting() {
|
||||
assertEquals(testSyncRefund_waitingOrSuccessOrFailure(PayRefundStatusRespEnum.WAITING.getStatus()), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyncRefund_success() {
|
||||
assertEquals(testSyncRefund_waitingOrSuccessOrFailure(PayRefundStatusRespEnum.SUCCESS.getStatus()), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyncRefund_failure() {
|
||||
assertEquals(testSyncRefund_waitingOrSuccessOrFailure(PayRefundStatusRespEnum.FAILURE.getStatus()), 1);
|
||||
}
|
||||
|
||||
private int testSyncRefund_waitingOrSuccessOrFailure(Integer status) {
|
||||
PayRefundServiceImpl payRefundServiceImpl = mock(PayRefundServiceImpl.class);
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PayRefundServiceImpl.class)))
|
||||
.thenReturn(payRefundServiceImpl);
|
||||
|
||||
// 准备参数
|
||||
PayRefundDO refund = randomPojo(PayRefundDO.class, o -> o.setAppId(1L).setChannelId(10L)
|
||||
.setStatus(PayRefundStatusEnum.WAITING.getStatus())
|
||||
.setOrderNo("P110").setNo("R220"));
|
||||
refundMapper.insert(refund);
|
||||
// mock 方法(client)
|
||||
PayClient client = mock(PayClient.class);
|
||||
when(payClientFactory.getPayClient(eq(10L))).thenReturn(client);
|
||||
// mock 方法(client 返回指定状态)
|
||||
PayRefundRespDTO respDTO = randomPojo(PayRefundRespDTO.class, o -> o.setStatus(status));
|
||||
when(client.getRefund(eq("P110"), eq("R220"))).thenReturn(respDTO);
|
||||
// mock 方法(channel)
|
||||
PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L));
|
||||
when(channelService.validPayChannel(eq(10L))).thenReturn(channel);
|
||||
|
||||
// 调用
|
||||
return refundService.syncRefund();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyncRefund_exception() {
|
||||
// 准备参数
|
||||
PayRefundDO refund = randomPojo(PayRefundDO.class, o -> o.setAppId(1L).setChannelId(10L)
|
||||
.setStatus(PayRefundStatusEnum.WAITING.getStatus())
|
||||
.setOrderNo("P110").setNo("R220"));
|
||||
refundMapper.insert(refund);
|
||||
// mock 方法(client)
|
||||
PayClient client = mock(PayClient.class);
|
||||
when(payClientFactory.getPayClient(eq(10L))).thenReturn(client);
|
||||
// mock 方法(client 抛出异常)
|
||||
when(client.getRefund(eq("P110"), eq("R220"))).thenThrow(new RuntimeException());
|
||||
|
||||
// 调用
|
||||
int count = refundService.syncRefund();
|
||||
// 断言
|
||||
assertEquals(count, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user