认证服务、广告管理、应用管理service单测剔除真实db使用mock mapper

This commit is contained in:
gaoqr
2026-01-15 11:58:12 +08:00
parent 76a1ad2003
commit 77120e4d3e
6 changed files with 366 additions and 188 deletions
@@ -1,7 +1,7 @@
package com.cf.imes.module.system.service.dict;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cf.imes.framework.common.enums.DeletedCodeEnum;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.pojo.PageResult;
@@ -86,11 +86,7 @@ public class DictTypeServiceImpl implements DictTypeService {
// 字典类型发生改变,更新关联字典数据
String oldDictTypeDOType = oldDictTypeDO.getType();
if (ObjectUtil.notEqual(oldDictTypeDOType, updateReqVOType)) {
UpdateWrapper<DictDataDO> wrapper = new UpdateWrapper<>();
wrapper.set("dict_type", updateReqVOType);
wrapper.eq("dict_type", oldDictTypeDOType);
wrapper.eq("status", DeletedCodeEnum.NOT_DELETED.getStatus());
dictDataMapper.update(wrapper);
dictDataMapper.update(new LambdaUpdateWrapper<DictDataDO>().set(DictDataDO::getDictType, updateReqVOType).eq(DictDataDO::getDictType, oldDictTypeDOType).eq(DictDataDO::getStatus, DeletedCodeEnum.NOT_DELETED.getStatus()));
}
}
@@ -82,7 +82,7 @@ public class AdvertisementServiceImpl implements AdvertisementService{
AdvertisementDO advertisementDO = validateAdvertisementExists(id);
// 发布中的广告不允许编辑
if (advertisementDO.getStatus().equals(AdvertisementStatusEnum.PUBLISHED.getStatus())) {
if (AdvertisementStatusEnum.PUBLISHED.getStatus().equals(advertisementDO.getStatus())) {
throw new ServiceException(ADVERTISEMENT_UPDATE_STATUS_ERROR);
}
@@ -1,38 +1,32 @@
package com.cf.imes.module.system.service.application;
import com.cf.imes.framework.test.core.ut.BaseDbAndRedisUnitTest;
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
import com.cf.imes.module.system.dal.dataobject.application.ApplicationDO;
import com.cf.imes.module.system.dal.mysql.application.ApplicationMapper;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import static com.cf.imes.framework.test.core.util.RandomUtils.randomPojo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.when;
/**
* 应用管理服务单元测试
*
* @author Gqr
* @since 2026/1/13 14:37
*/
@Import(ApplicationServiceImpl.class)
class ApplicationServiceImplTest extends BaseDbAndRedisUnitTest {
@Resource
class ApplicationServiceImplTest extends BaseMockitoUnitTest {
@InjectMocks
private ApplicationServiceImpl applicationService;
@Resource
@Mock
private ApplicationMapper applicationMapper;
@Test
void getApplicationByOrganId() {
Long organId = 1L;
ApplicationDO applicationDO = randomPojo(ApplicationDO.class, o -> {
o.setOrganId(organId);
});
ApplicationDO applicationDO = randomPojo(ApplicationDO.class);
applicationMapper.insert(applicationDO);
when(applicationMapper.selectByOrganId(organId)).thenReturn(applicationDO);
ApplicationDO applicationByOrganId = applicationService.getApplicationByOrganId(organId);
assertNotNull(applicationByOrganId);
@@ -9,9 +9,10 @@ import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.ip.core.service.IPQueryService;
import com.cf.imes.framework.ip.core.service.dto.IPQueryDataRespDTO;
import com.cf.imes.framework.organ.core.service.OrganFrameworkService;
import com.cf.imes.framework.security.core.LoginUser;
import com.cf.imes.framework.security.core.service.SecurityFrameworkService;
import com.cf.imes.framework.security.test.WithMockLoginUser;
import com.cf.imes.framework.test.core.ut.BaseDbUnitTest;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
import com.cf.imes.module.system.api.sms.SmsCodeApi;
import com.cf.imes.module.system.controller.admin.auth.vo.AuthLoginReqVO;
import com.cf.imes.module.system.controller.admin.auth.vo.AuthLoginSmsCheckReqVO;
@@ -36,10 +37,10 @@ import io.jsonwebtoken.security.Keys;
import jakarta.validation.Validator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import jakarta.annotation.Resource;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.mockito.MockedStatic;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionTemplate;
@@ -61,58 +62,57 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
@Import({AdminAuthServiceImpl.class, ChenfengProperties.class})
public class AdminAuthServiceImplTest extends BaseDbUnitTest {
class AdminAuthServiceImplTest extends BaseMockitoUnitTest {
@Resource
@InjectMocks
private AdminAuthServiceImpl authService;
@MockitoBean
@Mock
private AdminUserService userService;
@MockitoBean
@Mock
private CaptchaService captchaService;
@MockitoBean
@Mock
private LoginLogService loginLogService;
@MockitoBean
@Mock
private SmsCodeApi smsCodeApi;
@MockitoBean
@Mock
private OAuth2TokenService oauth2TokenService;
@MockitoBean
@Mock
private OrganService organService;
@MockitoBean
@Mock
private OrganFrameworkService organFrameworkService;
@MockitoBean
@Mock
private SmsCodeService smsCodeService;
@MockitoBean
@Mock
private IPQueryService ipQueryService;
@MockitoBean
@Mock
private TransactionTemplate transactionTemplate;
@MockitoBean
@Mock
private SecurityFrameworkService securityFrameworkService;
@MockitoBean
@Mock
private DeptService deptService;
@MockitoBean
@Mock
private ProductProperties productProperties;
@MockitoBean
@Mock
private JwtProperties jwtProperties;
@MockitoBean
@Mock
private ChenfengProperties chenfengProperties;
@MockitoBean
@Mock
private Validator validator;
private AuthLoginReqVO reqVO;
@@ -157,7 +157,7 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest {
@Test
void authenticate_passwordNotMatch_throwBadCredentials() {
AdminUserDO user = new AdminUserDO();
AdminUserDO user = buildUser();
when(userService.getUserUniqueByUserName("admin"))
.thenReturn(user);
@@ -529,7 +529,7 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest {
}
@Test
public void testLogout_success() {
void testLogout_success() {
// 准备参数
String token = randomString();
// mock
@@ -549,7 +549,7 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest {
}
@Test
public void testLogout_fail() {
void testLogout_fail() {
// 准备参数
String token = randomString();
@@ -579,8 +579,14 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest {
}
@Test
@WithMockLoginUser(userId = 123L, organId = 456L)
void testGetMesJwtToken() {
// mock 登录用户
LoginUser loginUser = new LoginUser();
loginUser.setId(123L);
loginUser.setOrganId(456L);
try (MockedStatic<SecurityFrameworkUtils> utilities = mockStatic(SecurityFrameworkUtils.class)) {
utilities.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
// mock jwtProperties
when(jwtProperties.getMesTokenTtl()).thenReturn(Duration.ofHours(1));
@@ -603,6 +609,7 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest {
assertEquals("test-aud", claims.getAudience());
assertNotNull(claims.getExpiration());
assertNotNull(claims.getNotBefore());
}
}
@Test
@@ -1,13 +1,18 @@
package com.cf.imes.module.system.service.dict;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
import com.cf.imes.module.system.controller.admin.dict.vo.type.DictTypePageReqVO;
import com.cf.imes.module.system.controller.admin.dict.vo.type.DictTypeSaveReqVO;
import com.cf.imes.module.system.dal.dataobject.dict.DictDataDO;
import com.cf.imes.module.system.dal.dataobject.dict.DictTypeDO;
import com.cf.imes.module.system.dal.mysql.dict.DictDataMapper;
import com.cf.imes.module.system.dal.mysql.dict.DictTypeMapper;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
@@ -42,6 +47,11 @@ public class DictTypeServiceImplTest extends BaseMockitoUnitTest {
@Mock
private DictDataService dictDataService;
@BeforeAll
static void init(){
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), DictDataDO.class);
}
@Test
void testGetDictTypePage_success() {
// 准备参数
@@ -147,13 +157,13 @@ public class DictTypeServiceImplTest extends BaseMockitoUnitTest {
when(dictTypeMapper.selectById(1L)).thenReturn(old);
when(dictTypeMapper.selectByType("new_type")).thenReturn(null);
when(dictTypeMapper.updateById(any(DictTypeDO.class))).thenReturn(1);
when(dictDataMapper.update(any(UpdateWrapper.class))).thenReturn(1);
when(dictDataMapper.update(any())).thenReturn(1);
dictTypeService.updateDictType(reqVO);
// 校验 dict_data 被批量更新
verify(dictDataMapper).update(
argThat((UpdateWrapper wrapper) ->
argThat((LambdaUpdateWrapper wrapper) ->
wrapper.getSqlSet().contains("dict_type")
)
);
@@ -1,7 +1,11 @@
package com.cf.imes.module.system.service.funds.advertisement;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.test.core.ut.BaseDbClearAfterClassAndRedisUnitTest;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
import com.cf.imes.module.infra.api.file.FileApi;
import com.cf.imes.module.system.controller.admin.funds.advertisement.vo.AdvertisementPageReqVO;
import com.cf.imes.module.system.controller.admin.funds.advertisement.vo.AdvertisementRePublishReqVO;
@@ -11,21 +15,20 @@ import com.cf.imes.module.system.dal.dataobject.funds.advertisement.Advertisemen
import com.cf.imes.module.system.dal.mysql.funds.advertisement.AdvertisementMapper;
import com.cf.imes.module.system.enums.advertisement.AdvertisementPositionEnum;
import com.cf.imes.module.system.enums.advertisement.AdvertisementStatusEnum;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.time.LocalDate;
import java.util.Collections;
import java.util.List;
import static com.cf.imes.framework.test.core.util.AssertUtils.assertServiceException;
import static com.cf.imes.framework.test.core.util.RandomUtils.randomPojo;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_IMAGE_EMPTY_ERROR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_IMAGE_UPLOAD_FAIL;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_NAME_IS_EXIST;
@@ -34,11 +37,15 @@ import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_N
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_STATUS_ENDTIME_EXPIRED;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_TIME_ERROR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_UPDATE_STATUS_ERROR;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
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.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -49,24 +56,22 @@ import static org.mockito.Mockito.when;
* @author Gqr
* @since 2025/10/28 10:15
*/
@Import(AdvertisementServiceImpl.class)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class AdvertisementServiceImplTest extends BaseDbClearAfterClassAndRedisUnitTest {
@Resource
private AdvertisementService advertisementService;
class AdvertisementServiceImplTest extends BaseMockitoUnitTest {
@InjectMocks
private AdvertisementServiceImpl advertisementService;
@Resource
@Mock
private AdvertisementMapper advertisementMapper;
@MockitoBean
@Mock
private FileApi fileApi;
private static AdvertisementDO insertedOne;
private static Long insertTwoId;
@BeforeAll
static void init(){
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), AdvertisementDO.class);
}
@Test
@Order(1)
void testCreate_whenStartTimeAfterEndTime_shouldThrow() {
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
reqVO.setStartTime(LocalDate.now().plusDays(1));
@@ -76,47 +81,70 @@ class AdvertisementServiceImplTest extends BaseDbClearAfterClassAndRedisUnitTest
}
@Test
@Order(2)
void testCreate_whenAdNameExists() {
// 1. 准备入参(时间必须合法)
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
reqVO.setAdName("TestAd");
reqVO.setStartTime(LocalDate.now());
reqVO.setEndTime(LocalDate.now().plusDays(1));
reqVO.setAdName("TestAd");
AdvertisementDO existing = randomPojo(AdvertisementDO.class, o -> o.setAdName("TestAd"));
advertisementMapper.insert(existing);
// 2. mock:广告名已存在
AdvertisementDO exist = new AdvertisementDO();
exist.setId(1L);
exist.setAdName("TestAd");
when(advertisementMapper.selectAdByAdName(
eq("TestAd"),
isNull()
)).thenReturn(exist);
assertServiceException(() -> advertisementService.create(reqVO), ADVERTISEMENT_NAME_IS_EXIST);
// 4. insert 一定不能被调用
verify(advertisementMapper, never()).insert(any(AdvertisementDO.class));
}
@Test
@Order(3)
void testCreate_success() {
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
reqVO.setStartTime(LocalDate.now());
reqVO.setEndTime(LocalDate.now().plusDays(1));
reqVO.setAdName("Ad-CREATE-1");
reqVO.setAdPosition(List.of(AdvertisementPositionEnum.BASECONFIG_FUNDSQUERY_CAROUSEL.getStatus()
reqVO.setAdPosition(List.of(AdvertisementPositionEnum.SYSTEMCONFIG_AMOUNTQUERY_CAROUSEL.getStatus()
, AdvertisementPositionEnum.WORKBENCH_CAROUSEL.getStatus()
, AdvertisementPositionEnum.BASECONFIG_FUNDSQUERY_CAROUSEL.getStatus()));
reqVO.setAdImagePath("https://example.com/image.png");
when(advertisementMapper.selectAdByAdName(eq("Ad-CREATE-1"), isNull()))
.thenReturn(null);
// 3. mock insert:模拟 MyBatis 回填 id
doAnswer(invocation -> {
AdvertisementDO ad = invocation.getArgument(0);
ad.setId(100L);
return 1;
}).when(advertisementMapper).insert(any(AdvertisementDO.class));
// 4. 调用方法
Long id = advertisementService.create(reqVO);
insertedOne = advertisementMapper.selectById(id);
// 5. 断言返回值
assertEquals(100L, id);
// 验证id
assertEquals(insertedOne.getId(), id);
// 验证 adPosition 去重排序
assertEquals(List.of(AdvertisementPositionEnum.WORKBENCH_CAROUSEL.getStatus(), AdvertisementPositionEnum.BASECONFIG_FUNDSQUERY_CAROUSEL.getStatus()), insertedOne.getAdPosition());
// 验证状态
assertEquals(AdvertisementStatusEnum.UNPUBLISHED.getStatus(), insertedOne.getStatus());
// 验证名称
assertEquals("Ad-CREATE-1", insertedOne.getAdName());
// 6. 捕获 insert 的参数,断言字段
ArgumentCaptor<AdvertisementDO> captor =
ArgumentCaptor.forClass(AdvertisementDO.class);
verify(advertisementMapper).insert(captor.capture());
AdvertisementDO saved = captor.getValue();
assertEquals("Ad-CREATE-1", saved.getAdName());
assertEquals(AdvertisementStatusEnum.UNPUBLISHED.getStatus(), saved.getStatus());
assertEquals(List.of(AdvertisementPositionEnum.WORKBENCH_CAROUSEL.getStatus()
, AdvertisementPositionEnum.SYSTEMCONFIG_AMOUNTQUERY_CAROUSEL.getStatus()
, AdvertisementPositionEnum.BASECONFIG_FUNDSQUERY_CAROUSEL.getStatus()), saved.getAdPosition());
}
@Test
@Order(4)
void testUpdate_whenStartTimeAfterEndTime() {
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
reqVO.setStartTime(LocalDate.now().plusDays(1));
@@ -126,7 +154,6 @@ class AdvertisementServiceImplTest extends BaseDbClearAfterClassAndRedisUnitTest
}
@Test
@Order(5)
void testUpdate_adExist(){
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
reqVO.setId(123L);
@@ -136,174 +163,301 @@ class AdvertisementServiceImplTest extends BaseDbClearAfterClassAndRedisUnitTest
}
@Test
@Order(5)
void testUpdate_whenAdNameExists() {
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
reqVO.setStartTime(LocalDate.now());
reqVO.setEndTime(LocalDate.now().plusDays(1));
reqVO.setAdName("Ad-CREATE-2");
reqVO.setAdPosition(List.of(AdvertisementPositionEnum.BASECONFIG_FUNDSQUERY_CAROUSEL.getStatus()
reqVO.setAdName("Ad-UPDATE-1");
AdvertisementDO exist = new AdvertisementDO();
when(advertisementMapper.selectOne(any()))
.thenReturn(exist);
when(advertisementMapper.selectAdByAdName(
eq("Ad-UPDATE-1"),
isNull()
)).thenReturn(exist);
assertServiceException(() -> advertisementService.update(reqVO), ADVERTISEMENT_NAME_IS_EXIST);
// 4. insert 一定不能被调用
verify(advertisementMapper, never()).updateById(any(AdvertisementDO.class));
}
@Test
void testUpdate_success() {
// ========== 1. mock:广告已存在 ==========
AdvertisementDO existing = new AdvertisementDO();
existing.setId(1L);
existing.setDeleted(false);
// validateAdvertisementExists() 内部会调用这个
when(advertisementMapper.selectOne(any()))
.thenReturn(existing);
// ========== 2. 构造更新请求 ==========
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
reqVO.setId(1L);
reqVO.setAdName("UpdatedAd");
reqVO.setStartTime(LocalDate.now());
reqVO.setEndTime(LocalDate.now().plusDays(1));
reqVO.setAdPosition(List.of(AdvertisementPositionEnum.SYSTEMCONFIG_AMOUNTQUERY_CAROUSEL.getStatus()
, AdvertisementPositionEnum.WORKBENCH_CAROUSEL.getStatus()
, AdvertisementPositionEnum.BASECONFIG_FUNDSQUERY_CAROUSEL.getStatus()));
reqVO.setAdImagePath("https://example.com/image.png");
insertTwoId = advertisementService.create(reqVO);
// ========== 3. 执行 ==========
advertisementService.update(reqVO);
AdvertisementSaveReqVO updateReqVO = new AdvertisementSaveReqVO();
updateReqVO.setId(insertedOne.getId());
updateReqVO.setStartTime(LocalDate.now());
updateReqVO.setEndTime(LocalDate.now().plusDays(1));
updateReqVO.setAdName("Ad-CREATE-2");
// ========== 4. 验证 updateById 被调用 ==========
ArgumentCaptor<AdvertisementDO> captor =
ArgumentCaptor.forClass(AdvertisementDO.class);
assertServiceException(() -> advertisementService.update(updateReqVO), ADVERTISEMENT_NAME_IS_EXIST);
verify(advertisementMapper).updateById(captor.capture());
AdvertisementDO updated = captor.getValue();
// ========== 5. 断言关键字段 ==========
assertEquals(1L, updated.getId());
assertEquals("UpdatedAd", updated.getAdName());
}
@Test
@Order(6)
void testUpdate_success() {
AdvertisementSaveReqVO updateReqVO = new AdvertisementSaveReqVO();
updateReqVO.setId(insertedOne.getId());
updateReqVO.setStartTime(LocalDate.now());
updateReqVO.setEndTime(LocalDate.now().plusDays(1));
updateReqVO.setAdName("Ad-UPDATE-1");
updateReqVO.setAdPosition(List.of(AdvertisementPositionEnum.WORKBENCH_CAROUSEL.getStatus()
, AdvertisementPositionEnum.BASECONFIG_FUNDSQUERY_CAROUSEL.getStatus()));
updateReqVO.setAdImagePath("https://example.com/image.jpg");
advertisementService.update(updateReqVO);
AdvertisementDO db = advertisementMapper.selectById(insertedOne.getId());
assertEquals(db.getAdName(), "Ad-UPDATE-1");
assertEquals(db.getAdPosition(), List.of(AdvertisementPositionEnum.WORKBENCH_CAROUSEL.getStatus()
, AdvertisementPositionEnum.BASECONFIG_FUNDSQUERY_CAROUSEL.getStatus()));
assertEquals(db.getAdImagePath(), "https://example.com/image.jpg");
}
@Test
@Order(7)
void testDelete_notExist() {
// mock 不存在
when(advertisementMapper.selectOne(any()))
.thenReturn(null);
assertServiceException(() -> advertisementService.delete(123L), ADVERTISEMENT_NO_EXIST);
// 不应该做任何删除
verify(advertisementMapper, never()).deleteById(any());
verify(fileApi, never()).deleteFileByPath(any());
}
@Test
@Order(8)
void testPublish_notExist(){
assertServiceException(() -> advertisementService.publish(123L), ADVERTISEMENT_NO_EXIST);
}
@Test
@Order(9)
void testUpdate_endTime_success() {
AdvertisementSaveReqVO updateReqVO = new AdvertisementSaveReqVO();
updateReqVO.setId(insertTwoId);
updateReqVO.setStartTime(LocalDate.now().minusDays(5));
updateReqVO.setEndTime(LocalDate.now().minusDays(4));
updateReqVO.setAdName("Ad-UPDATE-2");
updateReqVO.setAdPosition(List.of(AdvertisementPositionEnum.SYSTEMCONFIG_AMOUNTQUERY_CAROUSEL.getStatus()));
assertDoesNotThrow(() -> advertisementService.update(updateReqVO));
}
@Test
@Order(10)
void testPublish_endtime_expired() {
assertServiceException(() -> advertisementService.publish(insertTwoId), ADVERTISEMENT_STATUS_ENDTIME_EXPIRED);
Long adId = 1L;
AdvertisementDO ad = new AdvertisementDO()
.setId(adId)
.setEndTime(LocalDate.now().minusDays(1));
when(advertisementMapper.selectOne(any(LambdaQueryWrapperX.class))).thenReturn(ad);
assertServiceException(() -> advertisementService.publish(adId), ADVERTISEMENT_STATUS_ENDTIME_EXPIRED);
}
@Test
@Order(11)
void testPublish_success() {
advertisementService.publish(insertedOne.getId());
Long adId = 1L;
AdvertisementDO db = advertisementMapper.selectById(insertedOne.getId());
assertEquals(db.getStatus(), AdvertisementStatusEnum.PUBLISHED.getStatus());
AdvertisementDO ad = new AdvertisementDO()
.setId(adId)
.setEndTime(LocalDate.now().plusDays(1));
// 模拟 validateAdvertisementExists 返回广告
when(advertisementMapper.selectOne(any())).thenReturn(ad);
advertisementService.publish(adId);
// 验证 update 被调用
verify(advertisementMapper).update(argThat((LambdaUpdateWrapper wrapper) ->
wrapper.getSqlSet().contains("status")
));
}
@Test
@Order(12)
void testUpdate_published() {
AdvertisementSaveReqVO updateReqVO = new AdvertisementSaveReqVO();
updateReqVO.setId(insertedOne.getId());
updateReqVO.setStartTime(LocalDate.now());
updateReqVO.setEndTime(LocalDate.now());
AdvertisementDO exist = new AdvertisementDO();
exist.setStatus(AdvertisementStatusEnum.PUBLISHED.getStatus());
when(advertisementMapper.selectOne(any()))
.thenReturn(exist);
assertServiceException(() -> advertisementService.update(updateReqVO), ADVERTISEMENT_UPDATE_STATUS_ERROR);
}
@Test
@Order(13)
void testDelete_published() {
assertServiceException(() -> advertisementService.delete(insertedOne.getId()), ADVERTISEMENT_NO_DELETE);
AdvertisementDO published = new AdvertisementDO();
published.setId(1L);
published.setStatus(AdvertisementStatusEnum.PUBLISHED.getStatus());
published.setAdImagePath("/img/test.png");
when(advertisementMapper.selectOne(any()))
.thenReturn(published);
assertServiceException(() -> advertisementService.delete(1L), ADVERTISEMENT_NO_DELETE);
// 不删除 DB
verify(advertisementMapper, never()).deleteById(any());
// 不删除文件
verify(fileApi, never()).deleteFileByPath(any());
}
@Test
@Order(14)
void testEndPublish_notExist() {
assertServiceException(() -> advertisementService.endPublish(null), ADVERTISEMENT_NO_EXIST);
}
@Test
@Order(15)
void testGet_notExist() {
assertServiceException(() -> advertisementService.get(123L), ADVERTISEMENT_NO_EXIST);
}
@Test
@Order(16)
void testGet() {
assertNotNull(advertisementService.get(insertedOne.getId()));
AdvertisementDO ad = new AdvertisementDO();
ad.setId(1L);
ad.setAdName("TestAd");
ad.setStatus(AdvertisementStatusEnum.UNPUBLISHED.getStatus());
when(advertisementMapper.selectOne(any()))
.thenReturn(ad);
AdvertisementRespVO resp = advertisementService.get(1L);
assertNotNull(resp);
assertEquals(ad.getId(), resp.getId());
assertEquals(ad.getAdName(), resp.getAdName());
assertEquals(ad.getStatus(), resp.getStatus());
}
@Test
@Order(17)
void testGetByPosition() {
List<AdvertisementRespVO> advertisementRespVOS = advertisementService.getAdvertisementByPosition(AdvertisementPositionEnum.WORKBENCH_CAROUSEL.getStatus());
assertEquals(1, advertisementRespVOS.size());
Integer adPosition = 2;
AdvertisementRespVO vo = new AdvertisementRespVO();
vo.setId(1L);
vo.setAdName("测试广告");
advertisementRespVOS = advertisementService.getAdvertisementByPosition(AdvertisementPositionEnum.SYSTEMCONFIG_AMOUNTQUERY_CAROUSEL.getStatus());
assertEquals(0, advertisementRespVOS.size());
List<AdvertisementRespVO> mockList = List.of(vo);
when(advertisementMapper.selectAdList(
eq(adPosition),
eq(AdvertisementStatusEnum.PUBLISHED.getStatus()),
any(LocalDate.class)
)).thenReturn(mockList);
List<AdvertisementRespVO> result =
advertisementService.getAdvertisementByPosition(adPosition);
assertNotNull(result);
assertEquals(1, result.size());
assertSame(mockList, result);
}
@Test
@Order(18)
void testGetAdvertisementByPosition_empty() {
Integer adPosition = 1;
when(advertisementMapper.selectAdList(
eq(adPosition),
eq(AdvertisementStatusEnum.PUBLISHED.getStatus()),
any(LocalDate.class)
)).thenReturn(Collections.emptyList());
List<AdvertisementRespVO> result =
advertisementService.getAdvertisementByPosition(adPosition);
assertNotNull(result);
assertTrue(result.isEmpty());
}
@Test
void testEndPublish() {
advertisementService.endPublish(insertTwoId);
Long adId = 1L;
AdvertisementDO db = advertisementMapper.selectById(insertTwoId);
assertEquals(db.getStatus(), AdvertisementStatusEnum.ENDED.getStatus());
AdvertisementDO ad = new AdvertisementDO().setId(adId);
// 模拟 validateAdvertisementExists 返回广告
when(advertisementMapper.selectOne(any())).thenReturn(ad);
advertisementService.endPublish(adId);
// 验证 update 被调用
verify(advertisementMapper).update(argThat((LambdaUpdateWrapper wrapper) ->
wrapper.getSqlSet().contains("status")
));
}
@Test
@Order(19)
void testGetPage(){
AdvertisementPageReqVO pageReqVO = new AdvertisementPageReqVO();
pageReqVO.setStatus(AdvertisementStatusEnum.PUBLISHED.getStatus());
pageReqVO.setAdName("Ad-UPDATE-1");
AdvertisementPageReqVO reqVO = new AdvertisementPageReqVO();
PageResult<AdvertisementRespVO> page = advertisementService.getPage(pageReqVO);
assertEquals(1, page.getTotal());
AdvertisementDO ad1 = new AdvertisementDO()
.setId(1L)
.setAdName("Ad1")
.setStartTime(LocalDate.of(2026, 1, 15))
.setEndTime(LocalDate.of(2026, 1, 16));
pageReqVO.setStatus(AdvertisementStatusEnum.ENDED.getStatus());
pageReqVO.setAdName("Ad-UPDATE-2");
page = advertisementService.getPage(pageReqVO);
assertEquals(1, page.getTotal());
AdvertisementDO ad2 = new AdvertisementDO()
.setId(2L)
.setAdName("Ad2")
.setStartTime(LocalDate.of(2026, 1, 17))
.setEndTime(LocalDate.of(2026, 1, 18));
pageReqVO.setStatus(AdvertisementStatusEnum.UNPUBLISHED.getStatus());
page = advertisementService.getPage(pageReqVO);
assertEquals(0, page.getTotal());
PageResult<AdvertisementDO> page = new PageResult<>(List.of(ad1, ad2), 2L);
when(advertisementMapper.selectPage(reqVO)).thenReturn(page);
PageResult<AdvertisementRespVO> result = advertisementService.getPage(reqVO);
assertNotNull(result);
assertEquals(2, result.getList().size());
assertEquals(2L, result.getTotal());
AdvertisementRespVO resp1 = result.getList().get(0);
assertEquals("2026-01-15T00:00~2026-01-16T00:00", resp1.getLaunchTime());
AdvertisementRespVO resp2 = result.getList().get(1);
assertEquals("2026-01-17T00:00~2026-01-18T00:00", resp2.getLaunchTime());
}
@Test
void testGetPage_whenEmpty() {
AdvertisementPageReqVO reqVO = new AdvertisementPageReqVO();
PageResult<AdvertisementDO> emptyPage = new PageResult<>(0L); // total = 0
when(advertisementMapper.selectPage(reqVO)).thenReturn(emptyPage);
PageResult<AdvertisementRespVO> result = advertisementService.getPage(reqVO);
assertNotNull(result);
assertEquals(0, result.getList().size());
assertEquals(0L, result.getTotal());
}
@Test
@Order(20)
void testDelete_success() {
advertisementService.delete(insertTwoId);
AdvertisementDO db = advertisementMapper.selectById(insertTwoId);
assertNull(db);
AdvertisementDO draft = new AdvertisementDO();
draft.setId(1L);
draft.setStatus(AdvertisementStatusEnum.UNPUBLISHED.getStatus());
draft.setAdImagePath("/img/test.png");
when(advertisementMapper.selectOne(any()))
.thenReturn(draft);
// 执行
advertisementService.delete(1L);
// 删除数据库
verify(advertisementMapper).deleteById(1L);
// 删除文件
verify(fileApi).deleteFileByPath("/img/test.png");
}
@Test
@Order(21)
void testRepublish_notExist() {
AdvertisementRePublishReqVO reqVO = new AdvertisementRePublishReqVO();
reqVO.setId(null);
@@ -311,26 +465,43 @@ class AdvertisementServiceImplTest extends BaseDbClearAfterClassAndRedisUnitTest
}
@Test
@Order(22)
void testRepublish_time_error() {
Long id = 1L;
AdvertisementRePublishReqVO reqVO = new AdvertisementRePublishReqVO();
reqVO.setId(insertedOne.getId());
reqVO.setStartTime(LocalDate.now());
reqVO.setEndTime(LocalDate.now().minusDays(1));
reqVO.setId(id);
reqVO.setStartTime(LocalDate.now().plusDays(5));
reqVO.setEndTime(LocalDate.now());
// 广告存在
when(advertisementMapper.selectOne(any(LambdaQueryWrapperX.class)))
.thenReturn(new AdvertisementDO().setId(id));
assertServiceException(() -> advertisementService.republish(reqVO), ADVERTISEMENT_TIME_ERROR);
verify(advertisementMapper, never()).update(any());
}
@Test
@Order(23)
void testRepublish_success() {
Long id = 1L;
AdvertisementRePublishReqVO reqVO = new AdvertisementRePublishReqVO();
reqVO.setId(insertedOne.getId());
reqVO.setId(id);
reqVO.setStartTime(LocalDate.now());
reqVO.setEndTime(LocalDate.now().plusDays(1));
reqVO.setEndTime(LocalDate.now().plusDays(3));
// mock 广告存在
when(advertisementMapper.selectOne(any(LambdaQueryWrapperX.class)))
.thenReturn(new AdvertisementDO().setId(id));
advertisementService.republish(reqVO);
assertEquals(AdvertisementStatusEnum.PUBLISHED.getStatus(), advertisementMapper.selectById(insertedOne.getId()).getStatus());
verify(advertisementMapper).update(argThat((LambdaUpdateWrapper wrapper) ->
wrapper.getSqlSet().contains("status")
&& wrapper.getSqlSet().contains("start_time")
&& wrapper.getSqlSet().contains("end_time")
));
}
@Test