liu
2026-10-28 cc5438a25896d19f02b652865781dc443b274354
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package cn.iocoder.yudao.module.hrm.service.employee.listener;
 
import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO;
import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeEducationMapper;
import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeEmergencyContactMapper;
import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper;
import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeWorkHistoryMapper;
import cn.iocoder.yudao.module.system.api.user.event.AdminUserDeletedEvent;
import cn.iocoder.yudao.module.system.api.user.event.AdminUserUpdatedEvent;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import org.junit.jupiter.api.DisplayName;
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 org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
 
import java.util.Collections;
import java.util.List;
 
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
 
/**
 * 账号 -> 员工档案 同步监听器单元测试
 */
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class HrmEmployeeUserSyncListenerTest {
 
    private static final Long USER_ID = 200L;
 
    @Mock
    private HrmEmployeeMapper employeeMapper;
    @Mock
    private HrmEmployeeEducationMapper educationMapper;
    @Mock
    private HrmEmployeeWorkHistoryMapper workHistoryMapper;
    @Mock
    private HrmEmployeeEmergencyContactMapper emergencyContactMapper;
 
    @InjectMocks
    private HrmEmployeeUserSyncListener listener;
 
    private void mockEmployees(List<HrmEmployeeDO> employees) {
        when(employeeMapper.selectList(any(SFunction.class), eq(USER_ID))).thenReturn(employees);
    }
 
    @Test
    @DisplayName("删除账号:没有员工档案时直接跳过,不报错")
    void onUserDeleted_noEmployee_skip() {
        mockEmployees(Collections.emptyList());
 
        listener.onUserDeleted(new AdminUserDeletedEvent(USER_ID));
 
        verify(employeeMapper, never()).deleteById(anyLong());
        verifyNoInteractions(educationMapper, workHistoryMapper, emergencyContactMapper);
    }
 
    @Test
    @DisplayName("删除账号:存在 1 条员工档案时,联动删除员工及子表")
    void onUserDeleted_oneEmployee_deleteCascade() {
        mockEmployees(Collections.singletonList(HrmEmployeeDO.builder().id(10L).userId(USER_ID).build()));
 
        listener.onUserDeleted(new AdminUserDeletedEvent(USER_ID));
 
        verify(educationMapper).deleteByEmployeeId(10L);
        verify(workHistoryMapper).deleteByEmployeeId(10L);
        verify(emergencyContactMapper).deleteByEmployeeId(10L);
        verify(employeeMapper).deleteById(10L);
    }
 
    @Test
    @DisplayName("删除账号:存在多条员工档案时,不自动删除并跳过")
    void onUserDeleted_multiEmployees_skip() {
        mockEmployees(List.of(
                HrmEmployeeDO.builder().id(10L).userId(USER_ID).build(),
                HrmEmployeeDO.builder().id(11L).userId(USER_ID).build()));
 
        listener.onUserDeleted(new AdminUserDeletedEvent(USER_ID));
 
        verify(employeeMapper, never()).deleteById(anyLong());
        verifyNoInteractions(educationMapper, workHistoryMapper, emergencyContactMapper);
    }
 
    @Test
    @DisplayName("修改账号:没有员工档案时直接跳过")
    void onUserUpdated_noEmployee_skip() {
        mockEmployees(Collections.emptyList());
 
        listener.onUserUpdated(new AdminUserUpdatedEvent(USER_ID, "新名字", "13900000000", 11L, 2, "new@x.com"));
 
        verify(employeeMapper, never()).updateById(any(HrmEmployeeDO.class));
    }
 
    @Test
    @DisplayName("修改账号:回写可对应字段")
    void onUserUpdated_syncFields() {
        mockEmployees(Collections.singletonList(HrmEmployeeDO.builder().id(10L).userId(USER_ID).build()));
 
        listener.onUserUpdated(new AdminUserUpdatedEvent(USER_ID, "新名字", "13900000000", 11L, 2, "new@x.com"));
 
        ArgumentCaptor<HrmEmployeeDO> captor = ArgumentCaptor.forClass(HrmEmployeeDO.class);
        verify(employeeMapper).updateById(captor.capture());
        HrmEmployeeDO updateObj = captor.getValue();
        assertEquals(10L, updateObj.getId());
        assertEquals("新名字", updateObj.getName());
        assertEquals("13900000000", updateObj.getPhone());
        assertEquals(11L, updateObj.getDeptId());
        assertEquals(2, updateObj.getGender());
        assertEquals("new@x.com", updateObj.getEmail());
    }
 
    @Test
    @DisplayName("修改账号:性别未知(0)时不覆盖员工性别")
    void onUserUpdated_sexUnknown_notOverride() {
        mockEmployees(Collections.singletonList(HrmEmployeeDO.builder().id(10L).userId(USER_ID).build()));
 
        listener.onUserUpdated(new AdminUserUpdatedEvent(USER_ID, null, null, null, 0, null));
 
        ArgumentCaptor<HrmEmployeeDO> captor = ArgumentCaptor.forClass(HrmEmployeeDO.class);
        verify(employeeMapper).updateById(captor.capture());
        assertNull(captor.getValue().getGender());
        assertNull(captor.getValue().getName());
        assertNull(captor.getValue().getPhone());
    }
 
}