package com.ruoyi.chargingPile.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.ruoyi.chargingPile.api.dto.GetSiteListDTO;
|
import com.ruoyi.chargingPile.api.model.Site;
|
import com.ruoyi.chargingPile.api.model.TAccountingStrategyDetail;
|
import com.ruoyi.chargingPile.api.model.TChargingGun;
|
import com.ruoyi.chargingPile.api.model.TChargingPile;
|
import com.ruoyi.chargingPile.mapper.SiteMapper;
|
import com.ruoyi.chargingPile.service.IPartnerService;
|
import com.ruoyi.chargingPile.service.ITAccountingStrategyDetailService;
|
import com.ruoyi.chargingPile.service.ITChargingGunService;
|
import com.ruoyi.chargingPile.service.ITChargingPileService;
|
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.integration.api.feignClient.ChengDuJianGuanClient;
|
import com.ruoyi.integration.api.feignClient.IntegrationClient;
|
import com.ruoyi.integration.api.feignClient.TcecClient;
|
import com.ruoyi.system.api.domain.SysUser;
|
import com.ruoyi.system.api.feignClient.SysUserClient;
|
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.Test;
|
import org.springframework.test.util.ReflectionTestUtils;
|
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.List;
|
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.isNull;
|
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.timeout;
|
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.when;
|
|
class SiteServiceImplTest {
|
|
private SiteServiceImpl service;
|
private SiteMapper siteMapper;
|
private ITChargingGunService chargingGunService;
|
private ITAccountingStrategyDetailService accountingStrategyDetailService;
|
private ITChargingPileService chargingPileService;
|
private IntegrationClient integrationClient;
|
private ChengDuJianGuanClient chengDuJianGuanClient;
|
private TcecClient tcecClient;
|
|
@BeforeEach
|
void setUp() {
|
service = new SiteServiceImpl();
|
siteMapper = mock(SiteMapper.class);
|
chargingGunService = mock(ITChargingGunService.class);
|
accountingStrategyDetailService = mock(ITAccountingStrategyDetailService.class);
|
chargingPileService = mock(ITChargingPileService.class);
|
integrationClient = mock(IntegrationClient.class);
|
chengDuJianGuanClient = mock(ChengDuJianGuanClient.class);
|
tcecClient = mock(TcecClient.class);
|
|
ReflectionTestUtils.setField(service, "baseMapper", siteMapper);
|
ReflectionTestUtils.setField(service, "chargingGunService", chargingGunService);
|
ReflectionTestUtils.setField(service, "accountingStrategyDetailService", accountingStrategyDetailService);
|
ReflectionTestUtils.setField(service, "chargingPileService", chargingPileService);
|
ReflectionTestUtils.setField(service, "integrationClient", integrationClient);
|
ReflectionTestUtils.setField(service, "chengDuJianGuanClient", chengDuJianGuanClient);
|
ReflectionTestUtils.setField(service, "tcecClient", tcecClient);
|
}
|
|
@Test
|
void partnerSiteListIncludesAllSitesRelatedToCurrentPartner() {
|
IPartnerService partnerService = mock(IPartnerService.class);
|
SysUserClient sysUserClient = mock(SysUserClient.class);
|
ReflectionTestUtils.setField(service, "partnerService", partnerService);
|
ReflectionTestUtils.setField(service, "sysUserClient", sysUserClient);
|
|
SysUser sysUser = new SysUser();
|
sysUser.setUserId(100L);
|
sysUser.setRoleType(2);
|
sysUser.setObjectId(715);
|
|
when(sysUserClient.getSysUser(100L)).thenReturn(R.ok(sysUser));
|
when(siteMapper.getSiteOptions(isNull(), eq(715)))
|
.thenReturn(Collections.<GetSiteListDTO>emptyList());
|
|
service.getSiteList1(100L);
|
|
verify(siteMapper).getSiteOptions(isNull(), eq(715));
|
verify(partnerService, never()).authSite(any(), any());
|
verify(sysUserClient, never()).isAdmin(any());
|
}
|
|
/**
|
* 验证 setAccountingStrategy 使用 lambdaUpdate 只更新 accountingStrategyId 字段,
|
* 并且远程调用在异步线程中执行,避免事务长时间占用数据库连接
|
*/
|
@Test
|
void setAccountingStrategyUpdatesOnlyTargetFieldAndAsyncRemoteCalls() throws Exception {
|
Integer siteId = 1;
|
Integer accountingStrategyId = 100;
|
|
// mock 充电枪列表
|
List<TChargingGun> guns = new ArrayList<>();
|
TChargingGun gun = new TChargingGun();
|
gun.setId(10);
|
gun.setSiteId(siteId);
|
guns.add(gun);
|
|
// mock 充电桩列表
|
List<TChargingPile> piles = new ArrayList<>();
|
TChargingPile pile = new TChargingPile();
|
pile.setCode("PILE001");
|
pile.setId(200);
|
pile.setSiteId(siteId);
|
piles.add(pile);
|
|
// mock 计费策略明细
|
List<TAccountingStrategyDetail> details = new ArrayList<>();
|
|
// mock Site 查询(用于 isOpenSynchronization)
|
Site mockSite = new Site();
|
mockSite.setId(siteId);
|
mockSite.setIsOpenSynchronization(1);
|
|
when(siteMapper.selectList(any(LambdaQueryWrapper.class))).thenReturn(Collections.singletonList(mockSite));
|
when(chargingGunService.list(any(LambdaQueryWrapper.class))).thenReturn(guns);
|
when(accountingStrategyDetailService.list(any(LambdaQueryWrapper.class))).thenReturn(details);
|
|
assertDoesNotThrow(() -> service.setAccountingStrategy(siteId, accountingStrategyId));
|
|
// 验证数据库操作:站点和充电枪都通过 lambdaUpdate 更新
|
verify(siteMapper, atLeastOnce()).update(any(), any());
|
verify(siteMapper).selectList(any(LambdaQueryWrapper.class));
|
|
// 异步线程执行需要等待一小段时间
|
Thread.sleep(500);
|
|
// 验证远程调用在异步线程中执行
|
verify(integrationClient, timeout(1000)).setupBillingModel1(eq("PILE001"), any());
|
verify(chengDuJianGuanClient, timeout(1000)).notificationStationFee(eq(200));
|
verify(tcecClient, timeout(1000)).notificationStationChange(any());
|
}
|
|
/**
|
* 验证 setAccountingStrategy 在站点无需同步时不会调用三方平台推送
|
*/
|
@Test
|
void setAccountingStrategySkipsSyncWhenNotOpen() throws Exception {
|
Integer siteId = 2;
|
Integer accountingStrategyId = 200;
|
|
// mock 充电枪列表
|
TChargingGun gun = new TChargingGun();
|
gun.setId(20);
|
gun.setSiteId(siteId);
|
List<TChargingGun> guns = Collections.singletonList(gun);
|
|
// mock 充电桩列表
|
TChargingPile pile = new TChargingPile();
|
pile.setCode("PILE002");
|
pile.setId(201);
|
pile.setSiteId(siteId);
|
List<TChargingPile> piles = Collections.singletonList(pile);
|
|
List<TAccountingStrategyDetail> details = new ArrayList<>();
|
|
// isOpenSynchronization = 0,不需要同步
|
Site mockSite = new Site();
|
mockSite.setId(siteId);
|
mockSite.setIsOpenSynchronization(0);
|
|
when(siteMapper.selectList(any(LambdaQueryWrapper.class))).thenReturn(Collections.singletonList(mockSite));
|
when(chargingGunService.list(any(LambdaQueryWrapper.class))).thenReturn(guns);
|
when(accountingStrategyDetailService.list(any(LambdaQueryWrapper.class))).thenReturn(details);
|
|
assertDoesNotThrow(() -> service.setAccountingStrategy(siteId, accountingStrategyId));
|
|
Thread.sleep(500);
|
|
verify(integrationClient, timeout(1000)).setupBillingModel1(eq("PILE002"), any());
|
verify(chengDuJianGuanClient, timeout(1000)).notificationStationFee(eq(201));
|
// tcecClient.notificationStationChange 不应被调用
|
verify(tcecClient, never()).notificationStationChange(any());
|
}
|
}
|