ExceptionTest.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <?php
  2. declare(strict_types=1);
  3. namespace SixShop\Wangdian\Tests\Unit\Exception;
  4. use PHPUnit\Framework\TestCase;
  5. use SixShop\Wangdian\Exception\ApiException;
  6. use SixShop\Wangdian\Exception\AuthException;
  7. use SixShop\Wangdian\Exception\ConfigException;
  8. use SixShop\Wangdian\Exception\HttpException;
  9. use SixShop\Wangdian\Exception\ValidationException;
  10. use SixShop\Wangdian\Exception\WangdianException;
  11. class ExceptionTest extends TestCase
  12. {
  13. public function testWangdianExceptionBasic(): void
  14. {
  15. $message = 'Test exception message';
  16. $code = 123;
  17. $context = ['key' => 'value'];
  18. $exception = new class($message, $code, null, $context) extends WangdianException {};
  19. $this->assertEquals($message, $exception->getMessage());
  20. $this->assertEquals($code, $exception->getCode());
  21. $this->assertEquals($context, $exception->getContext());
  22. $this->assertInstanceOf(\Exception::class, $exception);
  23. $this->assertInstanceOf(WangdianException::class, $exception);
  24. }
  25. public function testWangdianExceptionWithPrevious(): void
  26. {
  27. $previous = new \Exception('Previous exception');
  28. $exception = new class('Test', 0, $previous) extends WangdianException {};
  29. $this->assertSame($previous, $exception->getPrevious());
  30. }
  31. public function testConfigException(): void
  32. {
  33. $message = 'Configuration error';
  34. $context = ['config_key' => 'invalid_value'];
  35. $exception = new ConfigException($message, 100, null, $context);
  36. $this->assertInstanceOf(WangdianException::class, $exception);
  37. $this->assertInstanceOf(ConfigException::class, $exception);
  38. $this->assertEquals($message, $exception->getMessage());
  39. $this->assertEquals(100, $exception->getCode());
  40. $this->assertEquals($context, $exception->getContext());
  41. }
  42. public function testAuthException(): void
  43. {
  44. $message = 'Authentication failed';
  45. $context = ['user_id' => '123'];
  46. $exception = new AuthException($message, 401, null, $context);
  47. $this->assertInstanceOf(WangdianException::class, $exception);
  48. $this->assertInstanceOf(AuthException::class, $exception);
  49. $this->assertEquals($message, $exception->getMessage());
  50. $this->assertEquals(401, $exception->getCode());
  51. $this->assertEquals($context, $exception->getContext());
  52. }
  53. public function testHttpException(): void
  54. {
  55. $message = 'HTTP request failed';
  56. $httpStatusCode = 500;
  57. $context = ['url' => 'https://api.example.com'];
  58. $exception = new HttpException($message, 0, null, $context, $httpStatusCode);
  59. $this->assertInstanceOf(WangdianException::class, $exception);
  60. $this->assertInstanceOf(HttpException::class, $exception);
  61. $this->assertEquals($message, $exception->getMessage());
  62. $this->assertEquals(0, $exception->getCode());
  63. $this->assertEquals($context, $exception->getContext());
  64. $this->assertEquals($httpStatusCode, $exception->getHttpStatusCode());
  65. }
  66. public function testHttpExceptionWithDefaults(): void
  67. {
  68. $exception = new HttpException();
  69. $this->assertEquals('', $exception->getMessage());
  70. $this->assertEquals(0, $exception->getCode());
  71. $this->assertNull($exception->getContext());
  72. $this->assertNull($exception->getHttpStatusCode());
  73. }
  74. public function testApiException(): void
  75. {
  76. $message = 'API error occurred';
  77. $apiCode = 'E1001';
  78. $responseData = ['error' => 'Invalid parameter', 'code' => 1001];
  79. $context = ['request_id' => 'req_123'];
  80. $exception = new ApiException($message, 0, null, $context, $apiCode, $responseData);
  81. $this->assertInstanceOf(WangdianException::class, $exception);
  82. $this->assertInstanceOf(ApiException::class, $exception);
  83. $this->assertEquals($message, $exception->getMessage());
  84. $this->assertEquals(0, $exception->getCode());
  85. $this->assertEquals($context, $exception->getContext());
  86. $this->assertEquals($apiCode, $exception->getApiCode());
  87. $this->assertEquals($responseData, $exception->getResponseData());
  88. }
  89. public function testApiExceptionWithDefaults(): void
  90. {
  91. $exception = new ApiException();
  92. $this->assertEquals('', $exception->getMessage());
  93. $this->assertEquals(0, $exception->getCode());
  94. $this->assertNull($exception->getContext());
  95. $this->assertNull($exception->getApiCode());
  96. $this->assertNull($exception->getResponseData());
  97. }
  98. public function testValidationException(): void
  99. {
  100. $message = 'Validation failed';
  101. $errors = ['field1' => 'Field 1 is required', 'field2' => 'Field 2 is invalid'];
  102. $context = ['form_id' => 'user_form'];
  103. $exception = new ValidationException($message, 422, null, $context, $errors);
  104. $this->assertInstanceOf(WangdianException::class, $exception);
  105. $this->assertInstanceOf(ValidationException::class, $exception);
  106. $this->assertEquals($message, $exception->getMessage());
  107. $this->assertEquals(422, $exception->getCode());
  108. $this->assertEquals($context, $exception->getContext());
  109. $this->assertEquals($errors, $exception->getErrors());
  110. }
  111. public function testValidationExceptionWithEmptyErrors(): void
  112. {
  113. $exception = new ValidationException('Test validation error');
  114. $this->assertEquals([], $exception->getErrors());
  115. }
  116. public function testExceptionInheritance(): void
  117. {
  118. $configException = new ConfigException();
  119. $authException = new AuthException();
  120. $httpException = new HttpException();
  121. $apiException = new ApiException();
  122. $validationException = new ValidationException();
  123. // All should inherit from WangdianException
  124. $this->assertInstanceOf(WangdianException::class, $configException);
  125. $this->assertInstanceOf(WangdianException::class, $authException);
  126. $this->assertInstanceOf(WangdianException::class, $httpException);
  127. $this->assertInstanceOf(WangdianException::class, $apiException);
  128. $this->assertInstanceOf(WangdianException::class, $validationException);
  129. // All should inherit from standard Exception
  130. $this->assertInstanceOf(\Exception::class, $configException);
  131. $this->assertInstanceOf(\Exception::class, $authException);
  132. $this->assertInstanceOf(\Exception::class, $httpException);
  133. $this->assertInstanceOf(\Exception::class, $apiException);
  134. $this->assertInstanceOf(\Exception::class, $validationException);
  135. }
  136. public function testExceptionChaining(): void
  137. {
  138. $rootCause = new \RuntimeException('Root cause');
  139. $httpException = new HttpException('HTTP error', 0, $rootCause);
  140. $apiException = new ApiException('API error', 0, $httpException);
  141. $this->assertSame($httpException, $apiException->getPrevious());
  142. $this->assertSame($rootCause, $apiException->getPrevious()->getPrevious());
  143. }
  144. public function testContextDataTypes(): void
  145. {
  146. $complexContext = [
  147. 'string' => 'value',
  148. 'integer' => 123,
  149. 'float' => 45.67,
  150. 'boolean' => true,
  151. 'array' => ['nested' => 'data'],
  152. 'null' => null,
  153. ];
  154. $exception = new ApiException('Test', 0, null, $complexContext);
  155. $this->assertEquals($complexContext, $exception->getContext());
  156. $this->assertIsString($exception->getContext()['string']);
  157. $this->assertIsInt($exception->getContext()['integer']);
  158. $this->assertIsFloat($exception->getContext()['float']);
  159. $this->assertIsBool($exception->getContext()['boolean']);
  160. $this->assertIsArray($exception->getContext()['array']);
  161. $this->assertNull($exception->getContext()['null']);
  162. }
  163. public function testUnicodeInExceptions(): void
  164. {
  165. $unicodeMessage = '错误信息:参数无效';
  166. $unicodeContext = ['错误码' => '1001', '描述' => '用户名包含非法字符'];
  167. $unicodeApiCode = 'E错误1001';
  168. $exception = new ApiException($unicodeMessage, 0, null, $unicodeContext, $unicodeApiCode);
  169. $this->assertEquals($unicodeMessage, $exception->getMessage());
  170. $this->assertEquals($unicodeContext, $exception->getContext());
  171. $this->assertEquals($unicodeApiCode, $exception->getApiCode());
  172. }
  173. }