| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- <?php
- namespace Tests\Unit\Farm;
- use Tests\TestCase;
- use App\Module\Farm\Logics\MysterySeeLLogic;
- use App\Module\Farm\Models\FarmMysterySeeLandEffect;
- use App\Module\Farm\Models\FarmSeedOutput;
- use App\Module\Farm\Models\FarmSeed;
- use Illuminate\Foundation\Testing\RefreshDatabase;
- use Illuminate\Support\Facades\Cache;
- class MysterySeeLLogicTest extends TestCase
- {
- use RefreshDatabase;
- protected MysterySeeLLogic $logic;
- protected function setUp(): void
- {
- parent::setUp();
- $this->logic = new MysterySeeLLogic();
-
- // 清除缓存
- Cache::flush();
- }
- /**
- * 测试概率覆盖值优先级高于修正值
- */
- public function testProbabilityOverrideVsModifier()
- {
- // 创建测试种子
- $seed = FarmSeed::factory()->create(['id' => 1]);
-
- // 创建基础产出配置
- FarmSeedOutput::factory()->create([
- 'seed_id' => 1,
- 'item_id' => 2,
- 'probability' => 10.0000,
- 'min_amount' => 1,
- 'max_amount' => 5,
- 'is_default' => false
- ]);
- // 创建测试数据:同时设置修正值和覆盖值
- FarmMysterySeeLandEffect::factory()->create([
- 'seed_id' => 1,
- 'land_type_id' => 6,
- 'output_item_id' => 2,
- 'probability_modifier' => 5.0000, // 修正值 +5%
- 'probability_override' => 30.0000, // 覆盖值 30%
- 'is_active' => true
- ]);
- $result = $this->logic->calculateAdjustedProbabilities(1, 6);
- // 应该使用覆盖值30%,而不是基础概率+修正值
- $item2Result = collect($result)->firstWhere('item_id', 2);
- $this->assertEquals(30.0000, $item2Result['adjusted_probability']);
- $this->assertEquals('override', $item2Result['adjustment_type']);
- }
- /**
- * 测试没有覆盖值时使用修正值
- */
- public function testProbabilityModifierWhenNoOverride()
- {
- // 创建测试种子
- $seed = FarmSeed::factory()->create(['id' => 1]);
-
- // 创建基础产出配置
- FarmSeedOutput::factory()->create([
- 'seed_id' => 1,
- 'item_id' => 2,
- 'probability' => 10.0000,
- 'min_amount' => 1,
- 'max_amount' => 5,
- 'is_default' => false
- ]);
- // 创建测试数据:只设置修正值
- FarmMysterySeeLandEffect::factory()->create([
- 'seed_id' => 1,
- 'land_type_id' => 2,
- 'output_item_id' => 2,
- 'probability_modifier' => 5.0000, // 修正值 +5%
- 'probability_override' => null, // 无覆盖值
- 'is_active' => true
- ]);
- $result = $this->logic->calculateAdjustedProbabilities(1, 2);
- // 应该使用基础概率+修正值
- $item2Result = collect($result)->firstWhere('item_id', 2);
- $this->assertEquals(15.0000, $item2Result['adjusted_probability']); // 10% + 5%
- $this->assertEquals('modifier', $item2Result['adjustment_type']);
- }
- /**
- * 测试概率边界值处理
- */
- public function testProbabilityBoundaries()
- {
- // 创建测试种子
- $seed = FarmSeed::factory()->create(['id' => 1]);
-
- // 创建基础产出配置
- FarmSeedOutput::factory()->create([
- 'seed_id' => 1,
- 'item_id' => 2,
- 'probability' => 5.0000,
- 'min_amount' => 1,
- 'max_amount' => 5,
- 'is_default' => false
- ]);
- // 测试负值修正导致概率小于0的情况
- FarmMysterySeeLandEffect::factory()->create([
- 'seed_id' => 1,
- 'land_type_id' => 1,
- 'output_item_id' => 2,
- 'probability_modifier' => -10.0000, // -10%,会导致负值
- 'probability_override' => null,
- 'is_active' => true
- ]);
- $result = $this->logic->calculateAdjustedProbabilities(1, 1);
- // 概率应该被限制在0以上
- $item2Result = collect($result)->firstWhere('item_id', 2);
- $this->assertEquals(0.0000, $item2Result['adjusted_probability']);
- }
- /**
- * 测试随机选择逻辑
- */
- public function testRandomSelection()
- {
- // 创建测试数据
- $outputs = [
- [
- 'item_id' => 2,
- 'min_amount' => 1,
- 'max_amount' => 5,
- 'adjusted_probability' => 50.0000,
- 'is_default' => false
- ],
- [
- 'item_id' => 3,
- 'min_amount' => 2,
- 'max_amount' => 6,
- 'adjusted_probability' => 30.0000,
- 'is_default' => true
- ],
- [
- 'item_id' => 4,
- 'min_amount' => 3,
- 'max_amount' => 7,
- 'adjusted_probability' => 20.0000,
- 'is_default' => false
- ]
- ];
- // 多次测试随机选择,验证结果在预期范围内
- $results = [];
- for ($i = 0; $i < 100; $i++) {
- $reflection = new \ReflectionClass($this->logic);
- $method = $reflection->getMethod('randomSelectOutput');
- $method->setAccessible(true);
-
- $result = $method->invoke($this->logic, $outputs);
- $results[] = $result['item_id'];
- }
- // 验证所有结果都在预期的物品ID范围内
- $uniqueResults = array_unique($results);
- $this->assertContains(2, $uniqueResults);
- $this->assertContains(3, $uniqueResults);
- $this->assertContains(4, $uniqueResults);
- }
- /**
- * 测试缓存功能
- */
- public function testCacheFunction()
- {
- // 创建测试种子
- $seed = FarmSeed::factory()->create(['id' => 1]);
-
- // 创建基础产出配置
- FarmSeedOutput::factory()->create([
- 'seed_id' => 1,
- 'item_id' => 2,
- 'probability' => 10.0000,
- 'min_amount' => 1,
- 'max_amount' => 5,
- 'is_default' => false
- ]);
- // 创建土地影响配置
- FarmMysterySeeLandEffect::factory()->create([
- 'seed_id' => 1,
- 'land_type_id' => 1,
- 'output_item_id' => 2,
- 'probability_modifier' => 5.0000,
- 'probability_override' => null,
- 'is_active' => true
- ]);
- // 第一次调用,应该从数据库查询
- $result1 = $this->logic->calculateAdjustedProbabilities(1, 1);
-
- // 第二次调用,应该从缓存获取
- $result2 = $this->logic->calculateAdjustedProbabilities(1, 1);
-
- // 结果应该相同
- $this->assertEquals($result1, $result2);
-
- // 清除缓存
- $this->logic->clearCache(1, 1);
-
- // 再次调用,应该重新从数据库查询
- $result3 = $this->logic->calculateAdjustedProbabilities(1, 1);
- $this->assertEquals($result1, $result3);
- }
- /**
- * 测试默认产出处理
- */
- public function testDefaultOutputHandling()
- {
- // 创建测试种子
- $seed = FarmSeed::factory()->create([
- 'id' => 1,
- 'item_id' => 100,
- 'min_output' => 1,
- 'max_output' => 3
- ]);
- // 不创建任何产出配置,测试默认处理
- $result = $this->logic->calculateAdjustedProbabilities(1, 1);
- // 应该返回种子的默认配置
- $this->assertCount(1, $result);
- $this->assertEquals(100, $result[0]['item_id']);
- $this->assertEquals(1, $result[0]['min_amount']);
- $this->assertEquals(3, $result[0]['max_amount']);
- $this->assertEquals(100, $result[0]['adjusted_probability']);
- $this->assertEquals('default', $result[0]['adjustment_type']);
- }
- /**
- * 测试异常处理
- */
- public function testExceptionHandling()
- {
- // 测试不存在的种子ID
- $this->expectException(\Exception::class);
- $this->expectExceptionMessage('种子ID 999 不存在');
-
- $reflection = new \ReflectionClass($this->logic);
- $method = $reflection->getMethod('getDefaultOutput');
- $method->setAccessible(true);
-
- $method->invoke($this->logic, 999);
- }
- }
|