diff --git a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapperTest.java b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapperTest.java index ce1bbac..f04459a 100644 --- a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapperTest.java +++ b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImPrivateMessageMapperTest.java @@ -5,7 +5,6 @@ import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO; import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; import jakarta.annotation.Resource; import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; import java.time.LocalDateTime; import java.util.List; @@ -17,7 +16,6 @@ import static org.junit.jupiter.api.Assertions.*; * * @author 芋道源码 */ -@Import(ImPrivateMessageMapper.class) public class ImPrivateMessageMapperTest extends BaseDbUnitTest { @Resource diff --git a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageServiceImplTest.java b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageServiceImplTest.java index 5ac285c..5f96582 100644 --- a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageServiceImplTest.java +++ b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageServiceImplTest.java @@ -1,24 +1,23 @@ package cn.iocoder.yudao.module.im.service.message; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; import cn.iocoder.yudao.module.im.controller.admin.message.vo.group.ImGroupMessageSendReqVO; import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO; import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; import cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO; import cn.iocoder.yudao.module.im.dal.mysql.message.ImGroupMessageMapper; import cn.iocoder.yudao.module.im.dal.redis.group.GroupReadPositionRedisDAO; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.module.im.enums.message.ImGroupMessageReceiptStatusEnum; import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; -import cn.iocoder.yudao.module.im.service.group.ImGroupService; import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService; +import cn.iocoder.yudao.module.im.service.group.ImGroupService; import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; -import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; 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 java.time.LocalDateTime; import java.util.*; @@ -28,14 +27,12 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; -// DONE @芋艿:已评估,23 个测试全部通过 /** * IM 群聊消息 Service 单元测试 * * @author 芋道源码 */ -@ExtendWith(MockitoExtension.class) -public class ImGroupMessageServiceImplTest { +public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest { @InjectMocks private ImGroupMessageServiceImpl groupMessageService; diff --git a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImplTest.java b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImplTest.java index 3d41ad2..598eabd 100644 --- a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImplTest.java +++ b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImplTest.java @@ -2,19 +2,18 @@ package cn.iocoder.yudao.module.im.service.message; import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; import cn.iocoder.yudao.module.im.controller.admin.message.vo.privates.ImPrivateMessageSendReqVO; import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO; import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper; import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; import cn.iocoder.yudao.module.im.service.friend.ImFriendService; import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; -import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockedStatic; -import org.mockito.junit.jupiter.MockitoExtension; import java.time.LocalDateTime; import java.util.List; @@ -29,8 +28,7 @@ import static org.mockito.Mockito.*; * * @author 芋道源码 */ -@ExtendWith(MockitoExtension.class) -public class ImPrivateMessageServiceImplTest { +public class ImPrivateMessageServiceImplTest extends BaseMockitoUnitTest { @InjectMocks private ImPrivateMessageServiceImpl privateMessageService; @@ -155,22 +153,28 @@ public class ImPrivateMessageServiceImplTest { @Test public void testReadMessages_success() { - // 准备:mock 未读消息列表 - List unreadMessages = List.of( - ImPrivateMessageDO.builder().id(1L).senderId(2L).receiverId(1L) - .status(ImMessageStatusEnum.UNREAD.getStatus()).build(), - ImPrivateMessageDO.builder().id(2L).senderId(2L).receiverId(1L) - .status(ImMessageStatusEnum.UNREAD.getStatus()).build() - ); - when(imPrivateMessageMapper.selectListBySenderIdAndReceiverIdAndStatus(2L, 1L, - ImMessageStatusEnum.UNREAD.getStatus())).thenReturn(unreadMessages); + try (MockedStatic springUtilMockedStatic = mockStatic(SpringUtil.class)) { + springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(ImPrivateMessageServiceImpl.class))) + .thenReturn(privateMessageService); - // 调用 - privateMessageService.readPrivateMessages(1L, 2L); + // 准备:mock 未读消息列表 + List unreadMessages = List.of( + ImPrivateMessageDO.builder().id(1L).senderId(2L).receiverId(1L) + .status(ImMessageStatusEnum.UNREAD.getStatus()).build(), + ImPrivateMessageDO.builder().id(2L).senderId(2L).receiverId(1L) + .status(ImMessageStatusEnum.UNREAD.getStatus()).build() + ); + when(imPrivateMessageMapper.selectListBySenderIdAndReceiverIdAndStatus(2L, 1L, + ImMessageStatusEnum.UNREAD.getStatus())).thenReturn(unreadMessages); - // 断言:更新了消息状态 + 发送了 READ 和 RECEIPT 事件 - verify(imPrivateMessageMapper).update(any(ImPrivateMessageDO.class), any()); - verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), anyString(), any()); + // 调用 + privateMessageService.readPrivateMessages(1L, 2L); + + // 断言:更新了消息状态 + 发送了 READ 和 RECEIPT 事件 + verify(imPrivateMessageMapper).updateByIdsAndStatus(eq(List.of(1L, 2L)), + eq(ImMessageStatusEnum.UNREAD.getStatus()), any(ImPrivateMessageDO.class)); + verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), anyString(), any()); + } } // ========== 撤回测试 ========== @@ -208,7 +212,8 @@ public class ImPrivateMessageServiceImplTest { // 准备 ImPrivateMessageDO message = ImPrivateMessageDO.builder() .id(10L).senderId(2L).receiverId(1L) - .status(ImMessageStatusEnum.UNREAD.getStatus()).build(); + .status(ImMessageStatusEnum.UNREAD.getStatus()) + .sendTime(LocalDateTime.now()).build(); when(imPrivateMessageMapper.selectById(10L)).thenReturn(message); // 调用并断言 @@ -222,7 +227,8 @@ public class ImPrivateMessageServiceImplTest { // 准备 ImPrivateMessageDO message = ImPrivateMessageDO.builder() .id(10L).senderId(1L).receiverId(2L) - .status(ImMessageStatusEnum.RECALL.getStatus()).build(); + .status(ImMessageStatusEnum.RECALL.getStatus()) + .sendTime(LocalDateTime.now()).build(); when(imPrivateMessageMapper.selectById(10L)).thenReturn(message); // 调用并断言 diff --git a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImWebSocketEventTest.java b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImWebSocketEventTest.java index 0a77d5f..cc4fd89 100644 --- a/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImWebSocketEventTest.java +++ b/yudao-module-im/yudao-module-im-biz/src/test/java/cn/iocoder/yudao/module/im/service/message/ImWebSocketEventTest.java @@ -1,26 +1,25 @@ package cn.iocoder.yudao.module.im.service.message; +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; import cn.iocoder.yudao.module.im.controller.admin.message.vo.privates.ImPrivateMessageSendReqVO; import cn.iocoder.yudao.module.im.dal.dataobject.message.ImPrivateMessageDO; import cn.iocoder.yudao.module.im.dal.mysql.message.ImPrivateMessageMapper; import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; +import cn.iocoder.yudao.module.im.service.friend.ImFriendService; +import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; import cn.iocoder.yudao.module.im.websocket.ImMessageReadMessage; import cn.iocoder.yudao.module.im.websocket.ImMessageReceiptMessage; -import cn.iocoder.yudao.module.im.websocket.ImMessageRecallMessage; import cn.iocoder.yudao.module.im.websocket.ImPrivateMessageSendMessage; -import cn.iocoder.yudao.module.im.service.friend.ImFriendService; -import cn.iocoder.yudao.module.im.service.sensitiveword.ImSensitiveWordService; -import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -31,8 +30,7 @@ import static org.mockito.Mockito.*; * * @author 芋道源码 */ -@ExtendWith(MockitoExtension.class) -public class ImWebSocketEventTest { +public class ImWebSocketEventTest extends BaseMockitoUnitTest { @InjectMocks private ImPrivateMessageServiceImpl privateMessageService; @@ -48,92 +46,104 @@ public class ImWebSocketEventTest { @Test public void testSendMessage_websocketEvent() { - // 准备 - ImPrivateMessageSendReqVO reqVO = new ImPrivateMessageSendReqVO(); - reqVO.setClientMessageId("evt-uuid"); - reqVO.setReceiverId(2L); - reqVO.setType(0); - reqVO.setContent("{\"content\":\"事件测试\"}"); - - when(imPrivateMessageMapper.selectBySenderIdAndClientMessageId(1L, "evt-uuid")).thenReturn(null); - // mock insert:通过 doAnswer 模拟 MyBatis-Plus 设置 ID - when(imPrivateMessageMapper.insert(any(ImPrivateMessageDO.class))).thenAnswer(invocation -> { - ImPrivateMessageDO msg = invocation.getArgument(0); - msg.setId(99L); - return 1; - }); - - // 调用 - privateMessageService.sendPrivateMessage(1L, reqVO); - - // 捕获 WebSocket 调用 - ArgumentCaptor typeCaptor = ArgumentCaptor.forClass(String.class); - ArgumentCaptor contentCaptor = ArgumentCaptor.forClass(Object.class); - verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), - typeCaptor.capture(), contentCaptor.capture()); - - // 验证消息事件类型 - assertEquals(ImPrivateMessageSendMessage.TYPE, typeCaptor.getAllValues().get(0)); - assertEquals(ImPrivateMessageSendMessage.TYPE, typeCaptor.getAllValues().get(1)); - - // 验证 payload 是 DTO 类型 - ImPrivateMessageSendMessage payload = (ImPrivateMessageSendMessage) contentCaptor.getAllValues().get(0); - assertNotNull(payload.getId(), "id 不应为空"); - assertEquals("1", payload.getSenderId()); - assertEquals("2", payload.getReceiverId()); + try (var springUtilMockedStatic = mockStatic(cn.hutool.extra.spring.SpringUtil.class)) { + springUtilMockedStatic.when(() -> cn.hutool.extra.spring.SpringUtil.getBean(eq(ImPrivateMessageServiceImpl.class))) + .thenReturn(privateMessageService); + + // 准备 + ImPrivateMessageSendReqVO reqVO = new ImPrivateMessageSendReqVO(); + reqVO.setClientMessageId("evt-uuid"); + reqVO.setReceiverId(2L); + reqVO.setType(0); + reqVO.setContent("{\"content\":\"事件测试\"}"); + + when(imPrivateMessageMapper.selectBySenderIdAndClientMessageId(1L, "evt-uuid")).thenReturn(null); + when(imPrivateMessageMapper.insert(any(ImPrivateMessageDO.class))).thenAnswer(invocation -> { + ImPrivateMessageDO msg = invocation.getArgument(0); + msg.setId(99L); + return 1; + }); + + // 调用 + privateMessageService.sendPrivateMessage(1L, reqVO); + + // 捕获 WebSocket 调用 + ArgumentCaptor typeCaptor = ArgumentCaptor.forClass(String.class); + ArgumentCaptor contentCaptor = ArgumentCaptor.forClass(Object.class); + verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), + typeCaptor.capture(), contentCaptor.capture()); + + // 验证消息事件类型 + assertEquals(ImPrivateMessageSendMessage.TYPE, typeCaptor.getAllValues().get(0)); + assertEquals(ImPrivateMessageSendMessage.TYPE, typeCaptor.getAllValues().get(1)); + + // 验证 payload 是 DTO 类型 + ImPrivateMessageSendMessage payload = (ImPrivateMessageSendMessage) contentCaptor.getAllValues().get(0); + assertNotNull(payload.getId(), "id 不应为空"); + assertEquals(1L, payload.getSenderId()); + assertEquals(2L, payload.getReceiverId()); + } } @Test public void testReadMessage_readAndReceiptEvents() { - // 准备:mock 未读消息 - List unreadMessages = List.of( - ImPrivateMessageDO.builder().id(1L).senderId(2L).receiverId(1L) - .status(ImMessageStatusEnum.UNREAD.getStatus()).build() - ); - when(imPrivateMessageMapper.selectListBySenderIdAndReceiverIdAndStatus(2L, 1L, - ImMessageStatusEnum.UNREAD.getStatus())).thenReturn(unreadMessages); - - // 调用 - privateMessageService.readPrivateMessages(1L, 2L); - - // 捕获 - ArgumentCaptor typeCaptor = ArgumentCaptor.forClass(String.class); - ArgumentCaptor userCaptor = ArgumentCaptor.forClass(Long.class); - verify(webSocketMessageSender, times(2)).sendObject(anyInt(), userCaptor.capture(), - typeCaptor.capture(), any()); - - // 第一次:发给自己的 READ 事件 - assertEquals(ImMessageReadMessage.TYPE, typeCaptor.getAllValues().get(0)); - assertEquals(1L, userCaptor.getAllValues().get(0)); - // 第二次:发给对方的 RECEIPT 事件 - assertEquals(ImMessageReceiptMessage.TYPE, typeCaptor.getAllValues().get(1)); - assertEquals(2L, userCaptor.getAllValues().get(1)); + try (var springUtilMockedStatic = mockStatic(cn.hutool.extra.spring.SpringUtil.class)) { + springUtilMockedStatic.when(() -> cn.hutool.extra.spring.SpringUtil.getBean(eq(ImPrivateMessageServiceImpl.class))) + .thenReturn(privateMessageService); + + // 准备:mock 未读消息 + List unreadMessages = List.of( + ImPrivateMessageDO.builder().id(1L).senderId(2L).receiverId(1L) + .status(ImMessageStatusEnum.UNREAD.getStatus()).build() + ); + when(imPrivateMessageMapper.selectListBySenderIdAndReceiverIdAndStatus(2L, 1L, + ImMessageStatusEnum.UNREAD.getStatus())).thenReturn(unreadMessages); + + // 调用 + privateMessageService.readPrivateMessages(1L, 2L); + + // 捕获 + ArgumentCaptor typeCaptor = ArgumentCaptor.forClass(String.class); + ArgumentCaptor userCaptor = ArgumentCaptor.forClass(Long.class); + verify(webSocketMessageSender, times(2)).sendObject(anyInt(), userCaptor.capture(), + typeCaptor.capture(), any()); + + // 第一次:发给自己的 READ 事件 + assertEquals(ImMessageReadMessage.TYPE, typeCaptor.getAllValues().get(0)); + assertEquals(1L, userCaptor.getAllValues().get(0)); + // 第二次:发给对方的 RECEIPT 事件 + assertEquals(ImMessageReceiptMessage.TYPE, typeCaptor.getAllValues().get(1)); + assertEquals(2L, userCaptor.getAllValues().get(1)); + } } @Test - public void testRecallMessage_recallEvent() { - // 准备 - ImPrivateMessageDO message = ImPrivateMessageDO.builder() - .id(10L).senderId(1L).receiverId(2L).status(0).build(); - when(imPrivateMessageMapper.selectById(10L)).thenReturn(message); - when(imPrivateMessageMapper.updateById(any(ImPrivateMessageDO.class))).thenReturn(1); - - // 调用 - privateMessageService.recallPrivateMessage(1L, 10L); - - // 捕获 - ArgumentCaptor typeCaptor = ArgumentCaptor.forClass(String.class); - ArgumentCaptor contentCaptor = ArgumentCaptor.forClass(Object.class); - verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), - typeCaptor.capture(), contentCaptor.capture()); - - // 验证 RECALL 事件类型 - assertEquals(ImMessageRecallMessage.TYPE, typeCaptor.getAllValues().get(0)); - - // 验证 payload - ImMessageRecallMessage payload = (ImMessageRecallMessage) contentCaptor.getAllValues().get(0); - assertEquals("10", payload.getMessageId()); - assertEquals("private", payload.getMessageScene()); + public void testRecallMessage_tipTextEvent() { + try (var springUtilMockedStatic = mockStatic(cn.hutool.extra.spring.SpringUtil.class)) { + springUtilMockedStatic.when(() -> cn.hutool.extra.spring.SpringUtil.getBean(eq(ImPrivateMessageServiceImpl.class))) + .thenReturn(privateMessageService); + + // 准备 + ImPrivateMessageDO message = ImPrivateMessageDO.builder() + .id(10L).senderId(1L).receiverId(2L).status(0) + .sendTime(java.time.LocalDateTime.now()).build(); + when(imPrivateMessageMapper.selectById(10L)).thenReturn(message); + when(imPrivateMessageMapper.updateById(any(ImPrivateMessageDO.class))).thenReturn(1); + when(imPrivateMessageMapper.insert(any(ImPrivateMessageDO.class))).thenReturn(1); + + // 调用 + privateMessageService.recallPrivateMessage(1L, 10L); + + // 捕获 + ArgumentCaptor typeCaptor = ArgumentCaptor.forClass(String.class); + ArgumentCaptor contentCaptor = ArgumentCaptor.forClass(Object.class); + verify(webSocketMessageSender, times(2)).sendObject(anyInt(), anyLong(), + typeCaptor.capture(), contentCaptor.capture()); + + // 验证:推送的是 TIP_TEXT 消息(通过 sendPrivateMessageEvent) + assertEquals(ImPrivateMessageSendMessage.TYPE, typeCaptor.getAllValues().get(0)); + assertEquals(ImPrivateMessageSendMessage.TYPE, typeCaptor.getAllValues().get(1)); + } } } diff --git a/yudao-module-im/yudao-module-im-biz/src/test/resources/application-unit-test.yaml b/yudao-module-im/yudao-module-im-biz/src/test/resources/application-unit-test.yaml index 4772788..b7bb631 100644 --- a/yudao-module-im/yudao-module-im-biz/src/test/resources/application-unit-test.yaml +++ b/yudao-module-im/yudao-module-im-biz/src/test/resources/application-unit-test.yaml @@ -1,37 +1,49 @@ spring: main: - lazy-initialization: true - banner-mode: off + lazy-initialization: true # 开启懒加载,加快速度 + banner-mode: off # 单元测试,禁用 Banner --- #################### 数据库相关配置 #################### spring: + # 数据源配置项 datasource: name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 driver-class-name: org.h2.Driver username: sa password: druid: - async-init: true - initial-size: 1 + async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 + initial-size: 1 # 单元测试,配置为 1,提升启动速度 sql: init: schema-locations: classpath:/sql/create_tables.sql encoding: UTF-8 + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 data: redis: - host: 127.0.0.1 - port: 16379 - database: 0 + host: 127.0.0.1 # 地址 + port: 16379 # 端口(单元测试,使用 16379 端口) + database: 0 # 数据库索引 -mybatis-plus: - lazy-initialization: true - type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject +mybatis: + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 + +--- #################### 定时任务相关配置 #################### + +--- #################### 配置中心相关配置 #################### + +--- #################### 服务保障相关配置 #################### + +# Lock4j 配置项(单元测试,禁用 Lock4j) + +--- #################### 监控相关配置 #################### --- #################### 芋道相关配置 #################### +# 芋道配置项,设置当前项目所有自定义的配置 yudao: info: - base-package: cn.iocoder.yudao + base-package: cn.iocoder.yudao.module