DisasterRemovalLogicTest.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <?php
  2. namespace Tests\Unit\Farm;
  3. use Tests\TestCase;
  4. use App\Module\Farm\Logics\DisasterRemovalLogic;
  5. use App\Module\Farm\Enums\DISASTER_TYPE;
  6. use App\Module\GameItems\Services\ItemService;
  7. use App\Module\Farm\Models\FarmLand;
  8. use App\Module\Farm\Models\FarmCrop;
  9. use Illuminate\Foundation\Testing\RefreshDatabase;
  10. use Illuminate\Support\Facades\DB;
  11. use UCore\Exception\LogicException;
  12. /**
  13. * 灾害去除逻辑测试
  14. */
  15. class DisasterRemovalLogicTest extends TestCase
  16. {
  17. use RefreshDatabase;
  18. private DisasterRemovalLogic $disasterRemovalLogic;
  19. protected function setUp(): void
  20. {
  21. parent::setUp();
  22. $this->disasterRemovalLogic = new DisasterRemovalLogic();
  23. }
  24. /**
  25. * 测试概率计算逻辑
  26. */
  27. public function testProbabilityCalculation()
  28. {
  29. // 使用反射来测试私有方法
  30. $reflection = new \ReflectionClass(DisasterRemovalLogic::class);
  31. $rollSuccessMethod = $reflection->getMethod('rollSuccess');
  32. $rollSuccessMethod->setAccessible(true);
  33. // 测试0%成功率
  34. $result = $rollSuccessMethod->invoke($this->disasterRemovalLogic, 0);
  35. $this->assertFalse($result, '0%成功率应该总是失败');
  36. // 测试100%成功率
  37. $result = $rollSuccessMethod->invoke($this->disasterRemovalLogic, 100);
  38. $this->assertTrue($result, '100%成功率应该总是成功');
  39. // 测试负数成功率
  40. $result = $rollSuccessMethod->invoke($this->disasterRemovalLogic, -10);
  41. $this->assertFalse($result, '负数成功率应该总是失败');
  42. // 测试超过100%的成功率
  43. $result = $rollSuccessMethod->invoke($this->disasterRemovalLogic, 150);
  44. $this->assertTrue($result, '超过100%的成功率应该总是成功');
  45. }
  46. /**
  47. * 测试灾害类型映射
  48. */
  49. public function testDisasterTypeMapping()
  50. {
  51. $reflection = new \ReflectionClass(DisasterRemovalLogic::class);
  52. // 获取常量
  53. $attributesConstant = $reflection->getConstant('DISASTER_ITEM_ATTRIBUTES');
  54. $namesConstant = $reflection->getConstant('DISASTER_ACTION_NAMES');
  55. // 验证映射关系
  56. $this->assertArrayHasKey(DISASTER_TYPE::DROUGHT->value, $attributesConstant);
  57. $this->assertArrayHasKey(DISASTER_TYPE::PEST->value, $attributesConstant);
  58. $this->assertArrayHasKey(DISASTER_TYPE::WEED->value, $attributesConstant);
  59. $this->assertEquals('fram_drought_rate', $attributesConstant[DISASTER_TYPE::DROUGHT->value]);
  60. $this->assertEquals('fram_pesticide_rate', $attributesConstant[DISASTER_TYPE::PEST->value]);
  61. $this->assertEquals('fram_weedicide_rate', $attributesConstant[DISASTER_TYPE::WEED->value]);
  62. $this->assertEquals('浇水', $namesConstant[DISASTER_TYPE::DROUGHT->value]);
  63. $this->assertEquals('除虫', $namesConstant[DISASTER_TYPE::PEST->value]);
  64. $this->assertEquals('除草', $namesConstant[DISASTER_TYPE::WEED->value]);
  65. }
  66. /**
  67. * 测试不支持的灾害类型
  68. */
  69. public function testUnsupportedDisasterType()
  70. {
  71. $this->expectException(LogicException::class);
  72. $this->expectExceptionMessage('不支持的灾害类型: 999');
  73. // 开启事务以满足事务检查要求
  74. DB::beginTransaction();
  75. try {
  76. $this->disasterRemovalLogic->removeDisaster(1, 1, 1, 999, 'test');
  77. } finally {
  78. DB::rollBack();
  79. }
  80. }
  81. /**
  82. * 测试事务检查
  83. */
  84. public function testTransactionCheck()
  85. {
  86. $this->expectException(\LogicException::class);
  87. $this->expectExceptionMessage('transaction level is 0');
  88. // 不开启事务,应该抛出异常
  89. $this->disasterRemovalLogic->removeDisaster(
  90. 1,
  91. 1,
  92. 1,
  93. DISASTER_TYPE::PEST->value,
  94. 'test'
  95. );
  96. }
  97. /**
  98. * 测试获取物品成功率
  99. */
  100. public function testGetItemSuccessRate()
  101. {
  102. $reflection = new \ReflectionClass(DisasterRemovalLogic::class);
  103. $getItemSuccessRateMethod = $reflection->getMethod('getItemSuccessRate');
  104. $getItemSuccessRateMethod->setAccessible(true);
  105. // Mock ItemService
  106. $this->mock(ItemService::class, function ($mock) {
  107. $mock->shouldReceive('getItemNumericAttribute')
  108. ->with(123, 'fram_pesticide_rate', 0)
  109. ->andReturn(80);
  110. });
  111. $result = $getItemSuccessRateMethod->invoke(
  112. $this->disasterRemovalLogic,
  113. 123,
  114. DISASTER_TYPE::PEST->value
  115. );
  116. $this->assertEquals(80, $result);
  117. }
  118. /**
  119. * 测试验证物品方法
  120. */
  121. public function testValidateItem()
  122. {
  123. $reflection = new \ReflectionClass(DisasterRemovalLogic::class);
  124. $validateItemMethod = $reflection->getMethod('validateItem');
  125. $validateItemMethod->setAccessible(true);
  126. // Mock ItemService - 用户没有物品的情况
  127. $this->mock(ItemService::class, function ($mock) {
  128. $mock->shouldReceive('getUserItems')
  129. ->with(1, ['item_id' => 123])
  130. ->andReturn(collect([])); // 空集合表示没有物品
  131. });
  132. $this->expectException(LogicException::class);
  133. $this->expectExceptionMessage('您没有该除虫物品');
  134. $validateItemMethod->invoke(
  135. $this->disasterRemovalLogic,
  136. 1, // userId
  137. 123, // itemId
  138. DISASTER_TYPE::PEST->value
  139. );
  140. }
  141. /**
  142. * 测试验证物品 - 物品没有对应属性
  143. */
  144. public function testValidateItemWithoutAttribute()
  145. {
  146. $reflection = new \ReflectionClass(DisasterRemovalLogic::class);
  147. $validateItemMethod = $reflection->getMethod('validateItem');
  148. $validateItemMethod->setAccessible(true);
  149. // Mock ItemService
  150. $this->mock(ItemService::class, function ($mock) {
  151. $mock->shouldReceive('getUserItems')
  152. ->with(1, ['item_id' => 123])
  153. ->andReturn(collect([new \stdClass()])); // 有物品
  154. $mock->shouldReceive('getItemNumericAttribute')
  155. ->with(123, 'fram_pesticide_rate')
  156. ->andReturn(0); // 没有对应属性或属性值为0
  157. });
  158. $this->expectException(LogicException::class);
  159. $this->expectExceptionMessage('不是除虫物品');
  160. $validateItemMethod->invoke(
  161. $this->disasterRemovalLogic,
  162. 1, // userId
  163. 123, // itemId
  164. DISASTER_TYPE::PEST->value
  165. );
  166. }
  167. }