BnbChainServiceTest.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <?php
  2. namespace App\Module\Blockchain\Tests\Unit\Services;
  3. use App\Module\Blockchain\Services\BnbChainService;
  4. use App\Module\Blockchain\Services\BscScanService;
  5. use App\Module\Blockchain\Enums\TokenType;
  6. use Tests\TestCase;
  7. use Illuminate\Support\Facades\Cache;
  8. use Web3\Web3;
  9. /**
  10. * BNB Chain 服务单元测试
  11. */
  12. class BnbChainServiceTest extends TestCase
  13. {
  14. protected BnbChainService $service;
  15. protected BscScanService $bscScanService;
  16. protected string $testAddress = '0x1234567890123456789012345678901234567890';
  17. protected string $testTxHash = '0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890';
  18. protected function setUp(): void
  19. {
  20. parent::setUp();
  21. $this->bscScanService = $this->createMock(BscScanService::class);
  22. $this->service = new BnbChainService($this->bscScanService, 'testnet');
  23. }
  24. /**
  25. * 测试获取网络配置
  26. * @test
  27. */
  28. public function testGetNetwork()
  29. {
  30. $network = $this->service->getNetwork();
  31. $this->assertEquals('BNB Smart Chain Testnet', $network['name']);
  32. $this->assertEquals(97, $network['chain_id']);
  33. $this->assertEquals('https://testnet.bscscan.com', $network['explorer']);
  34. }
  35. /**
  36. * 测试获取链 ID
  37. * @test
  38. */
  39. public function testGetChainId()
  40. {
  41. $this->assertEquals(97, $this->service->getChainId());
  42. }
  43. /**
  44. * 测试获取浏览器 URL
  45. * @test
  46. */
  47. public function testGetExplorerUrls()
  48. {
  49. $this->assertEquals(
  50. 'https://testnet.bscscan.com',
  51. $this->service->getExplorerUrl()
  52. );
  53. $this->assertEquals(
  54. 'https://testnet.bscscan.com/tx/' . $this->testTxHash,
  55. $this->service->getTransactionUrl($this->testTxHash)
  56. );
  57. $this->assertEquals(
  58. 'https://testnet.bscscan.com/address/' . $this->testAddress,
  59. $this->service->getAddressUrl($this->testAddress)
  60. );
  61. $tokenUrl = $this->service->getTokenUrl(TokenType::USDT);
  62. $this->assertStringContainsString('https://testnet.bscscan.com/token/', $tokenUrl);
  63. }
  64. /**
  65. * 测试 Gas 价格计算
  66. * @test
  67. */
  68. public function testGasPriceCalculation()
  69. {
  70. Cache::shouldReceive('remember')
  71. ->once()
  72. ->andReturn([
  73. 'safe_low' => 5,
  74. 'standard' => 6,
  75. 'fast' => 7,
  76. 'current' => 5.5
  77. ]);
  78. $gasPrice = $this->service->getGasPrice();
  79. $this->assertArrayHasKey('safe_low', $gasPrice);
  80. $this->assertArrayHasKey('standard', $gasPrice);
  81. $this->assertArrayHasKey('fast', $gasPrice);
  82. $this->assertArrayHasKey('current', $gasPrice);
  83. $this->assertGreaterThanOrEqual(5, $gasPrice['safe_low']);
  84. $this->assertGreaterThanOrEqual($gasPrice['safe_low'], $gasPrice['standard']);
  85. $this->assertGreaterThanOrEqual($gasPrice['standard'], $gasPrice['fast']);
  86. }
  87. /**
  88. * 测试 MEV 保护
  89. * @test
  90. */
  91. public function testMevProtection()
  92. {
  93. Cache::shouldReceive('remember')
  94. ->once()
  95. ->andReturn([
  96. 'safe_low' => 5,
  97. 'standard' => 6,
  98. 'fast' => 7,
  99. 'current' => 5.5
  100. ]);
  101. $mevPrice = $this->service->getMevProtectedGasPrice();
  102. $this->assertArrayHasKey('max_priority_fee_per_gas', $mevPrice);
  103. $this->assertArrayHasKey('max_fee_per_gas', $mevPrice);
  104. $this->assertLessThanOrEqual(10, $mevPrice['max_fee_per_gas']);
  105. $this->assertGreaterThan(0, $mevPrice['max_priority_fee_per_gas']);
  106. }
  107. /**
  108. * 测试交易确认检查
  109. * @test
  110. */
  111. public function testTransactionConfirmations()
  112. {
  113. // Mock 交易收据
  114. $this->bscScanService->method('getTransactionReceipt')
  115. ->willReturn([
  116. 'blockNumber' => '0x100' // 区块 256
  117. ]);
  118. // Mock 最新区块号
  119. Cache::shouldReceive('remember')
  120. ->once()
  121. ->andReturn(276); // 当前区块 276
  122. $confirmations = $this->service->getTransactionConfirmations($this->testTxHash);
  123. $this->assertEquals(20, $confirmations); // 276 - 256 = 20
  124. $isSafe = $this->service->isTransactionSafe($this->testTxHash);
  125. $this->assertTrue($isSafe); // 20 确认数已经安全
  126. }
  127. /**
  128. * 测试余额查询代理到 BscScanService
  129. * @test
  130. */
  131. public function testBalanceQueryDelegation()
  132. {
  133. $this->bscScanService->expects($this->once())
  134. ->method('getBalance')
  135. ->with($this->testAddress, TokenType::BNB)
  136. ->willReturn(1.5);
  137. $balance = $this->service->getBalance($this->testAddress, TokenType::BNB);
  138. $this->assertEquals(1.5, $balance);
  139. }
  140. /**
  141. * 测试交易历史查询代理到 BscScanService
  142. * @test
  143. */
  144. public function testTransactionHistoryDelegation()
  145. {
  146. $expectedHistory = [
  147. [
  148. 'hash' => $this->testTxHash,
  149. 'from' => $this->testAddress,
  150. 'to' => '0x0987654321098765432109876543210987654321',
  151. 'value' => '1000000000000000000'
  152. ]
  153. ];
  154. $this->bscScanService->expects($this->once())
  155. ->method('getTransactionHistory')
  156. ->with($this->testAddress, TokenType::BNB, 1, 10)
  157. ->willReturn($expectedHistory);
  158. $history = $this->service->getTransactionHistory($this->testAddress, TokenType::BNB);
  159. $this->assertEquals($expectedHistory, $history);
  160. }
  161. }