Commit 1781e76e19132ca35a7633936ed259ba479ba364

Authored by YunaiV
1 parent 902f2ecb

BPM 模型重构 7:任务分配规则的后端的单元测试

yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/definition/BpmTaskRuleScriptEnum.java
... ... @@ -11,9 +11,10 @@ import lombok.Getter;
11 11 */
12 12 @Getter
13 13 @AllArgsConstructor
14   -public class BpmTaskRuleScriptEnum {
  14 +public enum BpmTaskRuleScriptEnum {
15 15  
16   - ;
  16 + ONE(1L, ""),
  17 + TWO(2L, "");
17 18  
18 19 /**
19 20 * 脚本编号
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/config/BpmActivitiConfiguration.java
1 1 package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.config;
2 2  
3 3 import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.BpmActivityBehaviorFactory;
  4 +import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;
4 5 import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener.BpmTackActivitiEventListener;
5 6 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
  7 +import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
  8 +import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
6 9 import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
  10 +import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
7 11 import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
8 12 import org.springframework.context.annotation.Bean;
9 13 import org.springframework.context.annotation.Configuration;
10 14  
11 15 import java.util.Collections;
  16 +import java.util.List;
12 17  
13 18 import static org.activiti.spring.boot.ProcessEngineAutoConfiguration.BEHAVIOR_FACTORY_MAPPING_CONFIGURER;
14 19  
... ... @@ -47,10 +52,18 @@ public class BpmActivitiConfiguration {
47 52  
48 53 @Bean
49 54 public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService,
50   - SysPermissionService permissionService) {
  55 + SysPermissionService permissionService,
  56 + SysDeptService deptService,
  57 + BpmUserGroupService userGroupService,
  58 + SysUserService userService,
  59 + List<BpmTaskAssignScript> scripts) {
51 60 BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();
52 61 bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService);
53 62 bpmActivityBehaviorFactory.setPermissionService(permissionService);
  63 + bpmActivityBehaviorFactory.setDeptService(deptService);
  64 + bpmActivityBehaviorFactory.setUserGroupService(userGroupService);
  65 + bpmActivityBehaviorFactory.setUserService(userService);
  66 + bpmActivityBehaviorFactory.setScripts(scripts);
54 67 return bpmActivityBehaviorFactory;
55 68 }
56 69  
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/behavior/BpmActivityBehaviorFactory.java
1 1 package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior;
2 2  
  3 +import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;
3 4 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
  5 +import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
  6 +import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
4 7 import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
  8 +import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
5 9 import lombok.Data;
6 10 import lombok.EqualsAndHashCode;
7 11 import lombok.Setter;
... ... @@ -10,6 +14,9 @@ import org.activiti.bpmn.model.UserTask;
10 14 import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
11 15 import org.activiti.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory;
12 16  
  17 +import javax.annotation.Resource;
  18 +import java.util.List;
  19 +
13 20 /**
14 21 * 自定义的 ActivityBehaviorFactory 实现类,目的如下:
15 22 * 1. 自定义 {@link #createUserTaskActivityBehavior(UserTask)}:实现自定义的流程任务的 assignee 负责人的分配
... ... @@ -25,12 +32,24 @@ public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {
25 32 private BpmTaskAssignRuleService bpmTaskRuleService;
26 33 @Setter
27 34 private SysPermissionService permissionService;
  35 + @Setter
  36 + private SysDeptService deptService;
  37 + @Setter
  38 + private BpmUserGroupService userGroupService;
  39 + @Setter
  40 + private SysUserService userService;
  41 + @Setter
  42 + private List<BpmTaskAssignScript> scripts;
28 43  
29 44 @Override
30 45 public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {
31 46 BpmUserTaskActivitiBehavior userTaskActivityBehavior = new BpmUserTaskActivitiBehavior(userTask);
32 47 userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService);
33 48 userTaskActivityBehavior.setPermissionService(permissionService);
  49 + userTaskActivityBehavior.setDeptService(deptService);
  50 + userTaskActivityBehavior.setUserGroupService(userGroupService);
  51 + userTaskActivityBehavior.setUserService(userService);
  52 + userTaskActivityBehavior.setScripts(scripts);
34 53 return userTaskActivityBehavior;
35 54 }
36 55  
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/behavior/BpmUserTaskActivitiBehavior.java
... ... @@ -14,6 +14,8 @@ import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
14 14 import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
15 15 import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
16 16 import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
  17 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  18 +import com.google.common.annotations.VisibleForTesting;
17 19 import lombok.Setter;
18 20 import lombok.extern.slf4j.Slf4j;
19 21 import org.activiti.bpmn.model.UserTask;
... ... @@ -24,10 +26,7 @@ import org.activiti.engine.impl.el.ExpressionManager;
24 26 import org.activiti.engine.impl.persistence.entity.TaskEntity;
25 27 import org.activiti.engine.impl.persistence.entity.TaskEntityManager;
26 28  
27   -import javax.annotation.Resource;
28 29 import java.util.*;
29   -import java.util.function.Consumer;
30   -import java.util.function.Function;
31 30  
32 31 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.TASK_ASSIGN_SCRIPT_NOT_EXISTS;
33 32 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER;
... ... @@ -52,7 +51,7 @@ public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior {
52 51 private SysDeptService deptService;
53 52 @Setter
54 53 private BpmUserGroupService userGroupService;
55   - @Resource
  54 + @Setter
56 55 private SysUserService userService;
57 56 /**
58 57 * 任务分配脚本
... ... @@ -105,15 +104,18 @@ public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior {
105 104 return CollUtil.get(candidateUserIds, index);
106 105 }
107 106  
108   - private Set<Long> calculateTaskCandidateUsers(TaskEntity task, BpmTaskAssignRuleDO rule) {
  107 + @VisibleForTesting
  108 + Set<Long> calculateTaskCandidateUsers(TaskEntity task, BpmTaskAssignRuleDO rule) {
109 109 Set<Long> assigneeUserIds = null;
110 110 if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) {
111 111 assigneeUserIds = calculateTaskCandidateUsersByRole(task, rule);
112 112 } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) {
113   - assigneeUserIds = calculateTaskCandidateUsersByMember(task, rule);
  113 + assigneeUserIds = calculateTaskCandidateUsersByDeptMember(task, rule);
114 114 } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) {
115 115 assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(task, rule);
116   - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) {
  116 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) {
  117 + assigneeUserIds = calculateTaskCandidateUsersByPost(task, rule);
  118 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) {
117 119 assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule);
118 120 } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) {
119 121 assigneeUserIds = calculateTaskCandidateUsersByUserGroup(task, rule);
... ... @@ -121,7 +123,8 @@ public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior {
121 123 assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule);
122 124 }
123 125  
124   - // TODO 芋艿:统一过滤掉被禁用的用户
  126 + // 移除被禁用的用户
  127 + removeDisableUsers(assigneeUserIds);
125 128 // 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人
126 129 if (CollUtil.isEmpty(assigneeUserIds)) {
127 130 log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]",
... ... @@ -135,7 +138,7 @@ public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior {
135 138 return permissionService.getUserRoleIdListByRoleIds(rule.getOptions());
136 139 }
137 140  
138   - private Set<Long> calculateTaskCandidateUsersByMember(TaskEntity task, BpmTaskAssignRuleDO rule) {
  141 + private Set<Long> calculateTaskCandidateUsersByDeptMember(TaskEntity task, BpmTaskAssignRuleDO rule) {
139 142 List<SysUserDO> users = userService.getUsersByPostIds(rule.getOptions());
140 143 return convertSet(users, SysUserDO::getId);
141 144 }
... ... @@ -145,6 +148,11 @@ public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior {
145 148 return convertSet(depts, SysDeptDO::getLeaderUserId);
146 149 }
147 150  
  151 + private Set<Long> calculateTaskCandidateUsersByPost(TaskEntity task, BpmTaskAssignRuleDO rule) {
  152 + List<SysUserDO> users = userService.getUsersByPostIds(rule.getOptions());
  153 + return convertSet(users, SysUserDO::getId);
  154 + }
  155 +
148 156 private Set<Long> calculateTaskCandidateUsersByUser(TaskEntity task, BpmTaskAssignRuleDO rule) {
149 157 return rule.getOptions();
150 158 }
... ... @@ -172,4 +180,16 @@ public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior {
172 180 return userIds;
173 181 }
174 182  
  183 + @VisibleForTesting
  184 + void removeDisableUsers(Set<Long> assigneeUserIds) {
  185 + if (CollUtil.isEmpty(assigneeUserIds)) {
  186 + return;
  187 + }
  188 + Map<Long, SysUserDO> userMap = userService.getUserMap(assigneeUserIds);
  189 + assigneeUserIds.removeIf(id -> {
  190 + SysUserDO user = userMap.get(id);
  191 + return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus());
  192 + });
  193 + }
  194 +
175 195 }
... ...
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/behavior/BpmUserTaskActivitiBehaviorTest.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior;
  2 +
  3 +import cn.hutool.core.map.MapUtil;
  4 +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  5 +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmUserGroupDO;
  6 +import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
  7 +import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskRuleScriptEnum;
  8 +import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;
  9 +import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
  10 +import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
  11 +import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
  12 +import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
  13 +import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
  14 +import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
  15 +import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
  16 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  17 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  18 +import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
  19 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  20 +import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
  21 +import org.activiti.engine.impl.persistence.entity.TaskEntity;
  22 +import org.junit.jupiter.api.Test;
  23 +import org.mockito.InjectMocks;
  24 +import org.mockito.Mock;
  25 +import org.mockito.invocation.InvocationOnMock;
  26 +import org.mockito.stubbing.Answer;
  27 +
  28 +import java.util.*;
  29 +import java.util.function.Consumer;
  30 +import java.util.function.Function;
  31 +
  32 +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.*;
  33 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  34 +import static java.util.Collections.singletonList;
  35 +import static org.junit.jupiter.api.Assertions.*;
  36 +import static org.mockito.ArgumentMatchers.anySet;
  37 +import static org.mockito.ArgumentMatchers.eq;
  38 +import static org.mockito.Mockito.when;
  39 +
  40 +class BpmUserTaskActivitiBehaviorTest extends BaseMockitoUnitTest {
  41 +
  42 + @InjectMocks
  43 + private BpmUserTaskActivitiBehavior behavior;
  44 + @Mock
  45 + private BpmTaskAssignRuleService bpmTaskRuleService;
  46 + @Mock
  47 + private SysPermissionService permissionService;
  48 + @Mock
  49 + private SysDeptService deptService;
  50 + @Mock
  51 + private BpmUserGroupService userGroupService;
  52 + @Mock
  53 + private SysUserService userService;
  54 +
  55 + @Test
  56 + public void testCalculateTaskCandidateUsers_Role() {
  57 + // 准备参数
  58 + BpmTaskAssignRuleDO rule = new BpmTaskAssignRuleDO().setOptions(asSet(1L, 2L))
  59 + .setType(BpmTaskAssignRuleTypeEnum.ROLE.getType());
  60 + // mock 方法
  61 + when(permissionService.getUserRoleIdListByRoleIds(eq(rule.getOptions())))
  62 + .thenReturn(asSet(11L, 22L));
  63 + mockGetUserMap(asSet(11L, 22L));
  64 +
  65 + // 调用
  66 + Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  67 + // 断言
  68 + assertEquals(asSet(11L, 22L), results);
  69 + }
  70 +
  71 + @Test
  72 + public void testCalculateTaskCandidateUsers_DeptMember() {
  73 + // 准备参数
  74 + BpmTaskAssignRuleDO rule = new BpmTaskAssignRuleDO().setOptions(asSet(1L, 2L))
  75 + .setType(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType());
  76 + // mock 方法
  77 + List<SysUserDO> users = CollectionUtils.convertList(asSet(11L, 22L),
  78 + id -> new SysUserDO().setId(id));
  79 + when(userService.getUsersByPostIds(eq(rule.getOptions()))).thenReturn(users);
  80 + mockGetUserMap(asSet(11L, 22L));
  81 +
  82 + // 调用
  83 + Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  84 + // 断言
  85 + assertEquals(asSet(11L, 22L), results);
  86 + }
  87 +
  88 + @Test
  89 + public void testCalculateTaskCandidateUsers_DeptLeader() {
  90 + // 准备参数
  91 + BpmTaskAssignRuleDO rule = new BpmTaskAssignRuleDO().setOptions(asSet(1L, 2L))
  92 + .setType(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType());
  93 + // mock 方法
  94 + SysDeptDO dept1 = randomPojo(SysDeptDO.class, o -> o.setLeaderUserId(11L));
  95 + SysDeptDO dept2 = randomPojo(SysDeptDO.class, o -> o.setLeaderUserId(22L));
  96 + when(deptService.getDepts(eq(rule.getOptions()))).thenReturn(Arrays.asList(dept1, dept2));
  97 + mockGetUserMap(asSet(11L, 22L));
  98 +
  99 + // 调用
  100 + Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  101 + // 断言
  102 + assertEquals(asSet(11L, 22L), results);
  103 + }
  104 +
  105 + @Test
  106 + public void testCalculateTaskCandidateUsers_Post() {
  107 + // 准备参数
  108 + BpmTaskAssignRuleDO rule = new BpmTaskAssignRuleDO().setOptions(asSet(1L, 2L))
  109 + .setType(BpmTaskAssignRuleTypeEnum.POST.getType());
  110 + // mock 方法
  111 + List<SysUserDO> users = CollectionUtils.convertList(asSet(11L, 22L),
  112 + id -> new SysUserDO().setId(id));
  113 + when(userService.getUsersByPostIds(eq(rule.getOptions()))).thenReturn(users);
  114 + mockGetUserMap(asSet(11L, 22L));
  115 +
  116 + // 调用
  117 + Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  118 + // 断言
  119 + assertEquals(asSet(11L, 22L), results);
  120 + }
  121 +
  122 + @Test
  123 + public void testCalculateTaskCandidateUsers_User() {
  124 + // 准备参数
  125 + BpmTaskAssignRuleDO rule = new BpmTaskAssignRuleDO().setOptions(asSet(1L, 2L))
  126 + .setType(BpmTaskAssignRuleTypeEnum.USER.getType());
  127 + // mock 方法
  128 + mockGetUserMap(asSet(1L, 2L));
  129 +
  130 + // 调用
  131 + Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  132 + // 断言
  133 + assertEquals(asSet(1L, 2L), results);
  134 + }
  135 +
  136 + @Test
  137 + public void testCalculateTaskCandidateUsers_UserGroup() {
  138 + // 准备参数
  139 + BpmTaskAssignRuleDO rule = new BpmTaskAssignRuleDO().setOptions(asSet(1L, 2L))
  140 + .setType(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType());
  141 + // mock 方法
  142 + BpmUserGroupDO userGroup1 = randomPojo(BpmUserGroupDO.class, o -> o.setMemberUserIds(asSet(11L, 12L)));
  143 + BpmUserGroupDO userGroup2 = randomPojo(BpmUserGroupDO.class, o -> o.setMemberUserIds(asSet(21L, 22L)));
  144 + when(userGroupService.getUserGroupList(eq(rule.getOptions()))).thenReturn(Arrays.asList(userGroup1, userGroup2));
  145 + mockGetUserMap(asSet(11L, 12L, 21L, 22L));
  146 +
  147 + // 调用
  148 + Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  149 + // 断言
  150 + assertEquals(asSet(11L, 12L, 21L, 22L), results);
  151 + }
  152 +
  153 + @Test
  154 + public void testCalculateTaskCandidateUsers_Script() {
  155 + // 准备参数
  156 + BpmTaskAssignRuleDO rule = new BpmTaskAssignRuleDO().setOptions(asSet(1L, 2L))
  157 + .setType(BpmTaskAssignRuleTypeEnum.SCRIPT.getType());
  158 + // mock 方法
  159 + BpmTaskAssignScript script1 = new BpmTaskAssignScript() {
  160 +
  161 + @Override
  162 + public List<Long> calculateTaskCandidateUsers(TaskEntity task) {
  163 + return singletonList(11L);
  164 + }
  165 +
  166 + @Override
  167 + public BpmTaskRuleScriptEnum getEnum() {
  168 + return BpmTaskRuleScriptEnum.ONE;
  169 + }
  170 + };
  171 + BpmTaskAssignScript script2 = new BpmTaskAssignScript() {
  172 +
  173 + @Override
  174 + public List<Long> calculateTaskCandidateUsers(TaskEntity task) {
  175 + return singletonList(22L);
  176 + }
  177 +
  178 + @Override
  179 + public BpmTaskRuleScriptEnum getEnum() {
  180 + return BpmTaskRuleScriptEnum.TWO;
  181 + }
  182 + };
  183 + behavior.setScripts(Arrays.asList(script1, script2));
  184 + mockGetUserMap(asSet(11L, 22L));
  185 +
  186 + // 调用
  187 + Set<Long> results = behavior.calculateTaskCandidateUsers(null, rule);
  188 + // 断言
  189 + assertEquals(asSet(11L, 22L), results);
  190 + }
  191 +
  192 + @Test
  193 + public void testRemoveDisableUsers() {
  194 + // 准备参数
  195 + Set<Long> assigneeUserIds = asSet(1L, 2L, 3L);
  196 + // mock 方法
  197 + SysUserDO user1 = randomPojo(SysUserDO.class, o -> o.setId(1L));
  198 + SysUserDO user2 = randomPojo(SysUserDO.class, o -> o.setId(2L)
  199 + .setStatus(CommonStatusEnum.DISABLE.getStatus()));
  200 + Map<Long, SysUserDO> userMap = MapUtil.builder(user1.getId(), user1)
  201 + .put(user2.getId(), user2).build();
  202 + when(userService.getUserMap(eq(assigneeUserIds))).thenReturn(userMap);
  203 +
  204 + // 调用
  205 + behavior.removeDisableUsers(assigneeUserIds);
  206 + // 断言
  207 + assertEquals(asSet(1L), assigneeUserIds);
  208 + }
  209 +
  210 + private void mockGetUserMap(Set<Long> assigneeUserIds) {
  211 + Map<Long, SysUserDO> userMap = CollectionUtils.convertMap(assigneeUserIds, id -> id,
  212 + id -> new SysUserDO().setId(id).setStatus(CommonStatusEnum.ENABLE.getStatus()));
  213 + when(userService.getUserMap(eq(assigneeUserIds))).thenReturn(userMap);
  214 + }
  215 +
  216 +}
... ...