| | |
| | | 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() { |
| | | SiteServiceImpl service = new SiteServiceImpl(); |
| | | SiteMapper mapper = mock(SiteMapper.class); |
| | | IPartnerService partnerService = mock(IPartnerService.class); |
| | | SysUserClient sysUserClient = mock(SysUserClient.class); |
| | | ReflectionTestUtils.setField(service, "baseMapper", mapper); |
| | | ReflectionTestUtils.setField(service, "partnerService", partnerService); |
| | | ReflectionTestUtils.setField(service, "sysUserClient", sysUserClient); |
| | | |
| | |
| | | sysUser.setObjectId(715); |
| | | |
| | | when(sysUserClient.getSysUser(100L)).thenReturn(R.ok(sysUser)); |
| | | when(mapper.getSiteOptions(isNull(), eq(715))) |
| | | when(siteMapper.getSiteOptions(isNull(), eq(715))) |
| | | .thenReturn(Collections.<GetSiteListDTO>emptyList()); |
| | | |
| | | service.getSiteList1(100L); |
| | | |
| | | verify(mapper).getSiteOptions(isNull(), eq(715)); |
| | | 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()); |
| | | } |
| | | } |