Files
FendxPHP/tests/Unit/UserServiceTest.php

427 lines
12 KiB
PHP
Raw Permalink Normal View History

<?php
declare(strict_types=1);
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
use App\Service\UserService;
use App\Dao\UserDao;
use App\Dto\UserDto;
use App\Validate\UserValidator;
use Fendx\Security\Auth\JwtManager;
use Fendx\Security\Auth\RbacManager;
/**
* 用户服务单元测试
*/
class UserServiceTest extends TestCase
{
private UserService $userService;
private UserDao $userDao;
private UserValidator $validator;
private JwtManager $jwtManager;
private RbacManager $rbacManager;
protected function setUp(): void
{
parent::setUp();
// 创建 Mock 对象
$this->userDao = $this->createMock(UserDao::class);
$this->validator = $this->createMock(UserValidator::class);
$this->jwtManager = $this->createMock(JwtManager::class);
$this->rbacManager = $this->createMock(RbacManager::class);
// 创建服务实例
$this->userService = new UserService(
$this->userDao,
$this->validator,
$this->jwtManager,
$this->rbacManager
);
}
/**
* 测试用户注册成功
*/
public function testRegisterSuccess(): void
{
// 准备测试数据
$userData = [
'username' => 'testuser',
'email' => 'test@example.com',
'password' => 'password123',
'nickname' => 'Test User'
];
$request = $this->createMockRequest($userData);
// 设置 Mock 期望
$this->validator
->expects($this->once())
->method('validateRegisterFull')
->with($request)
->willReturn([]); // 无验证错误
$this->userDao
->expects($this->once())
->method('existsByUsername')
->with('testuser')
->willReturn(false);
$this->userDao
->expects($this->once())
->method('existsByEmail')
->with('test@example.com')
->willReturn(false);
$this->userDao
->expects($this->once())
->method('create')
->with($this->callback(function($userDto) use ($userData) {
return $userDto->getUsername() === $userData['username'] &&
$userDto->getEmail() === $userData['email'] &&
$userDto->getNickname() === $userData['nickname'];
}))
->willReturn(1);
// 执行测试
$result = $this->userService->register($request);
// 断言
$this->assertTrue($result['success']);
$this->assertEquals('注册成功', $result['message']);
$this->assertEquals(1, $result['user_id']);
}
/**
* 测试用户注册验证失败
*/
public function testRegisterValidationFailure(): void
{
$userData = [
'username' => '', // 空用户名
'email' => 'invalid-email', // 无效邮箱
'password' => '123', // 密码太短
];
$request = $this->createMockRequest($userData);
$this->validator
->expects($this->once())
->method('validateRegisterFull')
->with($request)
->willReturn([
'username' => '用户名必填',
'email' => '邮箱格式不正确',
'password' => '密码至少6位'
]);
$result = $this->userService->register($request);
$this->assertFalse($result['success']);
$this->assertEquals('验证失败', $result['message']);
$this->assertEquals([
'username' => '用户名必填',
'email' => '邮箱格式不正确',
'password' => '密码至少6位'
], $result['errors']);
}
/**
* 测试用户登录成功
*/
public function testLoginSuccess(): void
{
$loginData = [
'username' => 'testuser',
'password' => 'password123'
];
$request = $this->createMockRequest($loginData);
$userDto = new UserDto();
$userDto->setId(1)
->setUsername('testuser')
->setEmail('test@example.com')
->setPassword(password_hash('password123', PASSWORD_DEFAULT));
$this->validator
->expects($this->once())
->method('validateLogin')
->with($request)
->willReturn([]);
$this->userDao
->expects($this->once())
->method('findByUsername')
->with('testuser')
->willReturn($userDto);
$this->jwtManager
->expects($this->once())
->method('generate')
->with(['user_id' => 1, 'username' => 'testuser'])
->willReturn('jwt_token_here');
$result = $this->userService->login($request);
$this->assertTrue($result['success']);
$this->assertEquals('登录成功', $result['message']);
$this->assertEquals('jwt_token_here', $result['token']);
$this->assertEquals(1, $result['user']['id']);
$this->assertEquals('testuser', $result['user']['username']);
}
/**
* 测试用户登录失败 - 用户不存在
*/
public function testLoginUserNotFound(): void
{
$loginData = [
'username' => 'nonexistent',
'password' => 'password123'
];
$request = $this->createMockRequest($loginData);
$this->validator
->expects($this->once())
->method('validateLogin')
->with($request)
->willReturn([]);
$this->userDao
->expects($this->once())
->method('findByUsername')
->with('nonexistent')
->willReturn(null);
$result = $this->userService->login($request);
$this->assertFalse($result['success']);
$this->assertEquals('用户名或密码错误', $result['message']);
}
/**
* 测试获取用户信息成功
*/
public function testGetUserSuccess(): void
{
$userId = 1;
$userDto = new UserDto();
$userDto->setId(1)
->setUsername('testuser')
->setEmail('test@example.com')
->setNickname('Test User');
$this->userDao
->expects($this->once())
->method('findById')
->with($userId)
->willReturn($userDto);
$result = $this->userService->getUser($userId);
$this->assertTrue($result['success']);
$this->assertEquals('testuser', $result['user']['username']);
$this->assertEquals('test@example.com', $result['user']['email']);
$this->assertEquals('Test User', $result['user']['nickname']);
}
/**
* 测试获取用户信息失败 - 用户不存在
*/
public function testGetUserNotFound(): void
{
$userId = 999;
$this->userDao
->expects($this->once())
->method('findById')
->with($userId)
->willReturn(null);
$result = $this->userService->getUser($userId);
$this->assertFalse($result['success']);
$this->assertEquals('用户不存在', $result['message']);
}
/**
* 测试更新用户信息成功
*/
public function testUpdateUserSuccess(): void
{
$userId = 1;
$updateData = [
'nickname' => 'Updated User',
'phone' => '13800138000'
];
$request = $this->createMockRequest($updateData);
$existingUser = new UserDto();
$existingUser->setId(1)
->setUsername('testuser')
->setEmail('test@example.com');
$this->userDao
->expects($this->once())
->method('findById')
->with($userId)
->willReturn($existingUser);
$this->validator
->expects($this->once())
->method('validateUpdateFull')
->with($request, $userId)
->willReturn([]);
$this->userDao
->expects($this->once())
->method('update')
->with($this->callback(function($userDto) use ($updateData) {
return $userDto->getId() === 1 &&
$userDto->getNickname() === $updateData['nickname'] &&
$userDto->getPhone() === $updateData['phone'];
}))
->willReturn(true);
$result = $this->userService->updateUser($userId, $request);
$this->assertTrue($result['success']);
$this->assertEquals('更新成功', $result['message']);
}
/**
* 测试删除用户成功
*/
public function testDeleteUserSuccess(): void
{
$userId = 1;
$this->userDao
->expects($this->once())
->method('findById')
->with($userId)
->willReturn(new UserDto());
$this->userDao
->expects($this->once())
->method('delete')
->with($userId)
->willReturn(true);
$result = $this->userService->deleteUser($userId);
$this->assertTrue($result['success']);
$this->assertEquals('删除成功', $result['message']);
}
/**
* 测试用户权限检查
*/
public function testCheckUserPermission(): void
{
$userId = 1;
$permission = 'user:read';
$this->rbacManager
->expects($this->once())
->method('hasPermission')
->with($userId, $permission)
->willReturn(true);
$result = $this->userService->checkPermission($userId, $permission);
$this->assertTrue($result);
}
/**
* 测试用户角色分配
*/
public function testAssignUserRole(): void
{
$userId = 1;
$role = 'admin';
$this->rbacManager
->expects($this->once())
->method('assignRole')
->with($userId, $role)
->willReturn(true);
$result = $this->userService->assignRole($userId, $role);
$this->assertTrue($result['success']);
$this->assertEquals('角色分配成功', $result['message']);
}
/**
* 创建 Mock 请求对象
*/
private function createMockRequest(array $data): \Fendx\Web\Request\Request
{
$request = $this->createMock(\Fendx\Web\Request\Request::class);
$request->method('all')->willReturn($data);
$request->method('get')->willReturnCallback(fn($key) => $data[$key] ?? null);
$request->method('post')->willReturnCallback(fn($key) => $data[$key] ?? null);
return $request;
}
/**
* 测试用户密码加密
*/
public function testPasswordEncryption(): void
{
$password = 'password123';
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
$this->assertTrue(password_verify($password, $hashedPassword));
$this->assertFalse(password_verify('wrongpassword', $hashedPassword));
}
/**
* 测试 JWT 令牌生成
*/
public function testJwtTokenGeneration(): void
{
$payload = ['user_id' => 1, 'username' => 'testuser'];
$this->jwtManager
->expects($this->once())
->method('generate')
->with($payload)
->willReturn('mock_jwt_token');
$token = $this->jwtManager->generate($payload);
$this->assertEquals('mock_jwt_token', $token);
}
/**
* 测试数据验证器
*/
public function testUserValidator(): void
{
$this->validator
->expects($this->once())
->method('validateEmail')
->with('test@example.com')
->willReturn(true);
$this->validator
->expects($this->once())
->method('validatePhone')
->with('13800138000')
->willReturn(true);
$this->assertTrue($this->validator->validateEmail('test@example.com'));
$this->assertTrue($this->validator->validatePhone('13800138000'));
}
}