package com.ruoyi.order.service.impl;
|
|
import com.ruoyi.account.api.feignClient.AppUserIntegralChangeClient;
|
import com.ruoyi.chargingPile.api.feignClient.ChargingGunClient;
|
import com.ruoyi.chargingPile.api.feignClient.ChargingPileClient;
|
import com.ruoyi.chargingPile.api.feignClient.SiteClient;
|
import com.ruoyi.chargingPile.api.model.Site;
|
import com.ruoyi.chargingPile.api.model.TChargingGun;
|
import com.ruoyi.chargingPile.api.model.TChargingPile;
|
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.security.service.TokenService;
|
import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData;
|
import com.ruoyi.order.api.model.TChargingOrder;
|
import com.ruoyi.order.api.model.TVinChargingOrder;
|
import com.ruoyi.order.dto.ChargingDetails;
|
import com.ruoyi.order.mapper.TChargingOrderMapper;
|
import com.ruoyi.order.mapper.TVinChargingOrderMapper;
|
import com.ruoyi.order.util.mongodb.service.UploadRealTimeMonitoringDataService;
|
import com.ruoyi.order.vo.EndOfChargePageInfo;
|
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
import com.ruoyi.system.api.model.LoginUserApplet;
|
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.mockito.InjectMocks;
|
import org.mockito.Mock;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.springframework.test.util.ReflectionTestUtils;
|
|
import java.math.BigDecimal;
|
import java.time.LocalDateTime;
|
import java.util.Arrays;
|
import java.util.Collections;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.Mockito.when;
|
|
/**
|
* TChargingOrderServiceImpl 小程序接口对 VIN 码充电订单(t_vin_charging_order)的兜底逻辑测试:
|
* getChargingDetails(正在充电详情)、getEndOfChargePageInfo(结束页详情)。
|
*/
|
@ExtendWith(MockitoExtension.class)
|
class TChargingOrderServiceImplVinFallbackTest {
|
|
@InjectMocks
|
private TChargingOrderServiceImpl service;
|
@Mock
|
private TChargingOrderMapper mapper;
|
@Mock
|
private TVinChargingOrderMapper vinChargingOrderMapper;
|
@Mock
|
private TokenService tokenService;
|
@Mock
|
private ChargingGunClient chargingGunClient;
|
@Mock
|
private ChargingPileClient chargingPileClient;
|
@Mock
|
private SiteClient siteClient;
|
@Mock
|
private UploadRealTimeMonitoringDataService uploadRealTimeMonitoringDataService;
|
@Mock
|
private AppUserIntegralChangeClient appUserIntegralChangeClient;
|
|
/**
|
* 纯单测无 Spring 容器,MyBatis-Plus 的 lambda 列缓存需手工初始化,
|
* 否则 LambdaQueryWrapper 解析 getter 引用时抛 "can not find lambda cache"
|
*/
|
@BeforeAll
|
static void initMybatisPlusTableInfo() {
|
MapperBuilderAssistant assistant = new MapperBuilderAssistant(new MybatisConfiguration(), "");
|
TableInfoHelper.initTableInfo(assistant, TChargingOrder.class);
|
TableInfoHelper.initTableInfo(assistant, TVinChargingOrder.class);
|
}
|
|
@BeforeEach
|
void setUp() {
|
ReflectionTestUtils.setField(service, "baseMapper", mapper);
|
}
|
|
@Test
|
void getChargingDetailsFallsBackToVinOrderAndAssemblesRealTimeData() {
|
LoginUserApplet loginUser = new LoginUserApplet();
|
loginUser.setUserId(88L);
|
when(tokenService.getLoginUserApplet()).thenReturn(loginUser);
|
// 普通订单表查不到
|
when(mapper.selectOne(any())).thenReturn(null);
|
TVinChargingOrder vinOrder = new TVinChargingOrder();
|
vinOrder.setId(1001L);
|
vinOrder.setAppUserId(88L);
|
vinOrder.setChargingGunId(5);
|
vinOrder.setStatus(3);
|
vinOrder.setCode("VD20261013001");
|
vinOrder.setResidualAmount(new BigDecimal("66.60"));
|
when(vinChargingOrderMapper.selectOne(any())).thenReturn(vinOrder);
|
TChargingGun gun = new TChargingGun();
|
gun.setChargingPileId(7);
|
when(chargingGunClient.getChargingGunById(5)).thenReturn(R.ok(gun));
|
TChargingPile pile = new TChargingPile();
|
pile.setName("1号桩");
|
pile.setSiteId(9);
|
when(chargingPileClient.getChargingPileById(7)).thenReturn(R.ok(pile));
|
Site site = new Site();
|
site.setName("城东站");
|
when(siteClient.getSiteByIds(Arrays.asList(9))).thenReturn(R.ok(Collections.singletonList(site)));
|
UploadRealTimeMonitoringData data = new UploadRealTimeMonitoringData();
|
data.setOutput_current(new BigDecimal("10"));
|
data.setOutput_voltage(new BigDecimal("220"));
|
data.setSoc(50);
|
data.setTime_remaining(30);
|
data.setCharging_degree(new BigDecimal("5.5"));
|
data.setCumulative_charging_time(75);
|
when(uploadRealTimeMonitoringDataService.getLastDataById("VD20261013001")).thenReturn(data);
|
|
ChargingDetails details = service.getChargingDetails(5);
|
|
assertEquals("1001", details.getId());
|
assertEquals("城东站-1号桩", details.getName());
|
assertEquals("VD20261013001", details.getCode());
|
assertEquals(Integer.valueOf(3), details.getStatus());
|
assertEquals(0, new BigDecimal("66.60").compareTo(details.getChargingCost()));
|
assertEquals(0, new BigDecimal("10").compareTo(details.getChargeCurrent()));
|
assertEquals(0, new BigDecimal("220").compareTo(details.getChargeVoltage()));
|
assertEquals(0, new BigDecimal("2.200").compareTo(details.getChargePower()));
|
assertEquals(Integer.valueOf(50), details.getCompletionRatio());
|
assertEquals(Integer.valueOf(30), details.getRemainingChargeTime());
|
assertEquals(0, new BigDecimal("5.5").compareTo(details.getChargedDegrees()));
|
assertEquals("01:15", details.getChargedTime());
|
}
|
|
@Test
|
void getChargingDetailsReturnsNullWhenNeitherNormalNorVinOrderExists() {
|
LoginUserApplet loginUser = new LoginUserApplet();
|
loginUser.setUserId(88L);
|
when(tokenService.getLoginUserApplet()).thenReturn(loginUser);
|
when(mapper.selectOne(any())).thenReturn(null);
|
when(vinChargingOrderMapper.selectOne(any())).thenReturn(null);
|
|
assertNull(service.getChargingDetails(5));
|
}
|
|
@Test
|
void getEndOfChargePageInfoFallsBackToVinOrder() {
|
LoginUserApplet loginUser = new LoginUserApplet();
|
loginUser.setUserId(88L);
|
when(tokenService.getLoginUserApplet()).thenReturn(loginUser);
|
when(mapper.selectById("1001")).thenReturn(null);
|
TVinChargingOrder vinOrder = new TVinChargingOrder();
|
vinOrder.setId(1001L);
|
vinOrder.setAppUserId(88L);
|
vinOrder.setCode("VD20261013001");
|
vinOrder.setPaymentAmount(new BigDecimal("18.50"));
|
vinOrder.setRechargeAmount(new BigDecimal("50.00"));
|
vinOrder.setRefundAmount(new BigDecimal("31.50"));
|
vinOrder.setStartTime(LocalDateTime.of(2026, 10, 13, 10, 0));
|
vinOrder.setEndTime(LocalDateTime.of(2026, 10, 13, 11, 30));
|
when(vinChargingOrderMapper.selectById("1001")).thenReturn(vinOrder);
|
when(appUserIntegralChangeClient.getTAppUserIntegralChangeByOrderCode("VD20261013001"))
|
.thenReturn(R.ok(null));
|
|
EndOfChargePageInfo info = service.getEndOfChargePageInfo("1001");
|
|
assertEquals("1001", info.getId());
|
assertEquals("VD20261013001", info.getCode());
|
assertEquals(0, new BigDecimal("18.50").compareTo(info.getPaymentAmount()));
|
assertEquals(0, new BigDecimal("50.00").compareTo(info.getRechargeAmount()));
|
assertEquals(0, new BigDecimal("31.50").compareTo(info.getRefundAmount()));
|
assertEquals(Integer.valueOf(0), info.getIntegral());
|
assertEquals("10:00", info.getStartHour());
|
assertEquals("11:30", info.getEndHour());
|
assertEquals("1小时30分钟", info.getDuration());
|
}
|
|
@Test
|
void getEndOfChargePageInfoThrowsWhenOrderMissingInBothTables() {
|
// 两表均查不到订单时在获取登录用户之前即抛异常,tokenService 无需 stub
|
when(mapper.selectById("1001")).thenReturn(null);
|
when(vinChargingOrderMapper.selectById("1001")).thenReturn(null);
|
|
RuntimeException exception = null;
|
try {
|
service.getEndOfChargePageInfo("1001");
|
} catch (RuntimeException ex) {
|
exception = ex;
|
}
|
assertNotNull(exception);
|
assertEquals("充电订单不存在", exception.getMessage());
|
}
|
}
|