assertTrue( class_exists(BaseRequest::class), 'BaseRequest类应该存在' ); } /** * 测试BaseRequest是抽象类 */ public function testBaseRequestIsAbstract() { $reflection = new \ReflectionClass(BaseRequest::class); $this->assertTrue( $reflection->isAbstract(), 'BaseRequest应该是抽象类' ); } /** * 测试BaseRequest有必需的抽象方法 */ public function testBaseRequestHasRequiredAbstractMethods() { $reflection = new \ReflectionClass(BaseRequest::class); // 检查是否有handler抽象方法 $this->assertTrue( $reflection->hasMethod('handler'), 'BaseRequest应该有handler抽象方法' ); $handlerMethod = $reflection->getMethod('handler'); $this->assertTrue( $handlerMethod->isAbstract(), 'handler方法应该是抽象方法' ); $this->assertTrue( $handlerMethod->isProtected(), 'handler方法应该是protected' ); } /** * 测试BaseRequest有必需的公共方法 */ public function testBaseRequestHasRequiredPublicMethods() { $reflection = new \ReflectionClass(BaseRequest::class); // 检查request方法 $this->assertTrue( $reflection->hasMethod('request'), 'BaseRequest应该有request公共方法' ); $requestMethod = $reflection->getMethod('request'); $this->assertTrue( $requestMethod->isPublic(), 'request方法应该是public' ); } /** * 测试BaseRequest有必需的受保护方法 */ public function testBaseRequestHasRequiredProtectedMethods() { $reflection = new \ReflectionClass(BaseRequest::class); $expectedMethods = [ 'checkQuota', 'updateQuota', 'logRequest', 'getConfig', 'getService', 'getCredential', 'getRequestId' ]; foreach ($expectedMethods as $methodName) { $this->assertTrue( $reflection->hasMethod($methodName), "BaseRequest应该有{$methodName}方法" ); $method = $reflection->getMethod($methodName); $this->assertTrue( $method->isProtected(), "{$methodName}方法应该是protected" ); } } /** * 测试BaseRequest构造函数需要serviceCode参数 */ public function testBaseRequestConstructorRequiresServiceCode() { $reflection = new \ReflectionClass(BaseRequest::class); $constructor = $reflection->getConstructor(); $this->assertNotNull($constructor, 'BaseRequest应该有构造函数'); $parameters = $constructor->getParameters(); $this->assertCount(1, $parameters, '构造函数应该有1个参数'); $serviceCodeParam = $parameters[0]; $this->assertEquals('serviceCode', $serviceCodeParam->getName(), '参数名应该是serviceCode'); $this->assertEquals('string', $serviceCodeParam->getType()->getName(), '参数类型应该是string'); } /** * 测试BaseRequest有必需的属性 */ public function testBaseRequestHasRequiredProperties() { $reflection = new \ReflectionClass(BaseRequest::class); $expectedProperties = [ 'serviceCode', 'service', 'credential', 'requestId', 'startTime' ]; foreach ($expectedProperties as $propertyName) { $this->assertTrue( $reflection->hasProperty($propertyName), "BaseRequest应该有{$propertyName}属性" ); $property = $reflection->getProperty($propertyName); $this->assertTrue( $property->isProtected(), "{$propertyName}属性应该是protected" ); } } /** * 创建一个测试用的BaseRequest实现类 */ private function createTestRequestClass() { return new class('test_service') extends BaseRequest { protected function handler(array $params): array { return [ 'success' => true, 'message' => '测试请求处理成功', 'params' => $params, 'service_code' => $this->serviceCode, 'request_id' => $this->requestId, ]; } // 重写方法以避免数据库依赖 protected function initializeService(): void { // 跳过服务初始化 } protected function checkQuota(): bool { return true; } protected function updateQuota(): void { // 跳过配额更新 } protected function logRequest(array $params, array $result, bool $success): void { // 跳过日志记录 } protected function getConfig(?string $key = null) { $config = ['test_key' => 'test_value']; return $key ? ($config[$key] ?? null) : $config; } }; } /** * 测试BaseRequest的基本功能 */ public function testBaseRequestBasicFunctionality() { $testRequest = $this->createTestRequestClass(); // 测试request方法可以调用 $result = $testRequest->request(['test_param' => 'test_value']); $this->assertIsArray($result, 'request方法应该返回数组'); $this->assertTrue($result['success'], '测试请求应该成功'); $this->assertEquals('测试请求处理成功', $result['message']); $this->assertEquals(['test_param' => 'test_value'], $result['params']); $this->assertEquals('test_service', $result['service_code']); $this->assertNotEmpty($result['request_id'], '应该有请求ID'); } /** * 测试BaseRequest的单一职责原则设计 */ public function testBaseRequestSingleResponsibilityDesign() { $reflection = new \ReflectionClass(BaseRequest::class); // BaseRequest应该只有一个抽象方法handler $abstractMethods = $reflection->getMethods(\ReflectionMethod::IS_ABSTRACT); $this->assertCount(1, $abstractMethods, 'BaseRequest应该只有一个抽象方法'); $this->assertEquals('handler', $abstractMethods[0]->getName(), '抽象方法应该是handler'); // 这确保了每个子类只需要实现一个handler方法,符合单一职责原则 } /** * 测试BaseRequest的错误处理机制 */ public function testBaseRequestErrorHandling() { $testRequest = new class('test_service') extends BaseRequest { protected function handler(array $params): array { throw new \Exception('测试异常'); } // 重写方法以避免数据库依赖 protected function initializeService(): void {} protected function checkQuota(): bool { return true; } protected function updateQuota(): void {} protected function logRequest(array $params, array $result, bool $success): void {} protected function getConfig(?string $key = null) { return []; } }; // 测试异常会被正确抛出 $this->expectException(\Exception::class); $this->expectExceptionMessage('测试异常'); $testRequest->request([]); } }