package com.ruoyi.user.service.impl; 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.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; 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 com.ruoyi.common.core.constant.UserConstants; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.user.config.UniversalCodeProperties; import com.ruoyi.user.domain.AccountUser; import com.ruoyi.user.mapper.AccountUserMapper; /** * 会员注册服务单元测试 * * 覆盖通用推荐码放行、无效/停用推荐码拒绝、正常绑定推荐人三分支。 * * @author hugray */ @ExtendWith(MockitoExtension.class) class AccountUserServiceImplTest { private static final String PHONE = "13800000000"; private static final String UNIVERSAL_CODE = "HUGRAY88"; @Mock private AccountUserMapper accountUserMapper; @Mock private UniversalCodeProperties universalCodeProperties; @InjectMocks private AccountUserServiceImpl accountUserService; @Test @DisplayName("命中通用推荐码应注册成功且不绑定推荐人") void registerMember_shouldNotBindReferrer_whenUniversalCodeHit() { when(universalCodeProperties.getUniversalReferralCode()).thenReturn(UNIVERSAL_CODE); when(accountUserMapper.selectAccountUserByPhone(PHONE)).thenReturn(null); when(accountUserMapper.selectAccountUserByReferralCode(anyString())).thenReturn(null); when(accountUserMapper.insertAccountUser(any(AccountUser.class))).thenReturn(1); accountUserService.registerMember(PHONE, UNIVERSAL_CODE); ArgumentCaptor captor = ArgumentCaptor.forClass(AccountUser.class); verify(accountUserMapper).insertAccountUser(captor.capture()); AccountUser saved = captor.getValue(); assertNull(saved.getReferrerUserId()); assertNotNull(saved.getMyReferralCode()); // 通用码不参与推荐人定位 verify(accountUserMapper, never()).selectAccountUserByReferralCode(UNIVERSAL_CODE); } @Test @DisplayName("未配置通用推荐码且推荐码无效时应拒绝注册") void registerMember_shouldThrow_whenReferralCodeInvalid() { when(universalCodeProperties.getUniversalReferralCode()).thenReturn(null); when(accountUserMapper.selectAccountUserByPhone(PHONE)).thenReturn(null); when(accountUserMapper.selectAccountUserByReferralCode("BADCODE")).thenReturn(null); ServiceException ex = assertThrows(ServiceException.class, () -> accountUserService.registerMember(PHONE, "BADCODE")); assertEquals("推荐人码无效", ex.getMessage()); } @Test @DisplayName("推荐人账号停用时应拒绝注册") void registerMember_shouldThrow_whenReferrerDisabled() { AccountUser referrer = new AccountUser(); referrer.setUserId(100L); referrer.setStatus(UserConstants.USER_DISABLE); when(universalCodeProperties.getUniversalReferralCode()).thenReturn(null); when(accountUserMapper.selectAccountUserByPhone(PHONE)).thenReturn(null); when(accountUserMapper.selectAccountUserByReferralCode("VALID123")).thenReturn(referrer); ServiceException ex = assertThrows(ServiceException.class, () -> accountUserService.registerMember(PHONE, "VALID123")); assertEquals("推荐人账号异常", ex.getMessage()); } @Test @DisplayName("推荐码有效时应绑定推荐人") void registerMember_shouldBindReferrer_whenReferralCodeValid() { AccountUser referrer = new AccountUser(); referrer.setUserId(100L); referrer.setStatus(UserConstants.NORMAL); when(universalCodeProperties.getUniversalReferralCode()).thenReturn(null); when(accountUserMapper.selectAccountUserByPhone(PHONE)).thenReturn(null); // 仅 "VALID123" 命中推荐人;其余(本人推荐码查重)返回 null,避免影响唯一码生成 when(accountUserMapper.selectAccountUserByReferralCode(anyString())) .thenAnswer(invocation -> "VALID123".equals(invocation.getArgument(0)) ? referrer : null); when(accountUserMapper.insertAccountUser(any(AccountUser.class))).thenReturn(1); accountUserService.registerMember(PHONE, "VALID123"); ArgumentCaptor captor = ArgumentCaptor.forClass(AccountUser.class); verify(accountUserMapper).insertAccountUser(captor.capture()); assertEquals(100L, captor.getValue().getReferrerUserId()); } }