disasterRemovalLogic = new DisasterRemovalLogic(); } /** * 测试概率计算逻辑 */ public function testProbabilityCalculation() { // 使用反射来测试私有方法 $reflection = new \ReflectionClass(DisasterRemovalLogic::class); $rollSuccessMethod = $reflection->getMethod('rollSuccess'); $rollSuccessMethod->setAccessible(true); // 测试0%成功率 $result = $rollSuccessMethod->invoke($this->disasterRemovalLogic, 0); $this->assertFalse($result, '0%成功率应该总是失败'); // 测试100%成功率 $result = $rollSuccessMethod->invoke($this->disasterRemovalLogic, 100); $this->assertTrue($result, '100%成功率应该总是成功'); // 测试负数成功率 $result = $rollSuccessMethod->invoke($this->disasterRemovalLogic, -10); $this->assertFalse($result, '负数成功率应该总是失败'); // 测试超过100%的成功率 $result = $rollSuccessMethod->invoke($this->disasterRemovalLogic, 150); $this->assertTrue($result, '超过100%的成功率应该总是成功'); } /** * 测试灾害类型映射 */ public function testDisasterTypeMapping() { $reflection = new \ReflectionClass(DisasterRemovalLogic::class); // 获取常量 $attributesConstant = $reflection->getConstant('DISASTER_ITEM_ATTRIBUTES'); $namesConstant = $reflection->getConstant('DISASTER_ACTION_NAMES'); // 验证映射关系 $this->assertArrayHasKey(DISASTER_TYPE::DROUGHT->value, $attributesConstant); $this->assertArrayHasKey(DISASTER_TYPE::PEST->value, $attributesConstant); $this->assertArrayHasKey(DISASTER_TYPE::WEED->value, $attributesConstant); $this->assertEquals('fram_drought_rate', $attributesConstant[DISASTER_TYPE::DROUGHT->value]); $this->assertEquals('fram_pesticide_rate', $attributesConstant[DISASTER_TYPE::PEST->value]); $this->assertEquals('fram_weedicide_rate', $attributesConstant[DISASTER_TYPE::WEED->value]); $this->assertEquals('浇水', $namesConstant[DISASTER_TYPE::DROUGHT->value]); $this->assertEquals('除虫', $namesConstant[DISASTER_TYPE::PEST->value]); $this->assertEquals('除草', $namesConstant[DISASTER_TYPE::WEED->value]); } /** * 测试不支持的灾害类型 */ public function testUnsupportedDisasterType() { $this->expectException(LogicException::class); $this->expectExceptionMessage('不支持的灾害类型: 999'); // 开启事务以满足事务检查要求 DB::beginTransaction(); try { $this->disasterRemovalLogic->removeDisaster(1, 1, 1, 999, 'test'); } finally { DB::rollBack(); } } /** * 测试事务检查 */ public function testTransactionCheck() { $this->expectException(\LogicException::class); $this->expectExceptionMessage('transaction level is 0'); // 不开启事务,应该抛出异常 $this->disasterRemovalLogic->removeDisaster( 1, 1, 1, DISASTER_TYPE::PEST->value, 'test' ); } /** * 测试获取物品成功率 */ public function testGetItemSuccessRate() { $reflection = new \ReflectionClass(DisasterRemovalLogic::class); $getItemSuccessRateMethod = $reflection->getMethod('getItemSuccessRate'); $getItemSuccessRateMethod->setAccessible(true); // Mock ItemService $this->mock(ItemService::class, function ($mock) { $mock->shouldReceive('getItemNumericAttribute') ->with(123, 'fram_pesticide_rate', 0) ->andReturn(80); }); $result = $getItemSuccessRateMethod->invoke( $this->disasterRemovalLogic, 123, DISASTER_TYPE::PEST->value ); $this->assertEquals(80, $result); } /** * 测试验证物品方法 */ public function testValidateItem() { $reflection = new \ReflectionClass(DisasterRemovalLogic::class); $validateItemMethod = $reflection->getMethod('validateItem'); $validateItemMethod->setAccessible(true); // Mock ItemService - 用户没有物品的情况 $this->mock(ItemService::class, function ($mock) { $mock->shouldReceive('getUserItems') ->with(1, ['item_id' => 123]) ->andReturn(collect([])); // 空集合表示没有物品 }); $this->expectException(LogicException::class); $this->expectExceptionMessage('您没有该除虫物品'); $validateItemMethod->invoke( $this->disasterRemovalLogic, 1, // userId 123, // itemId DISASTER_TYPE::PEST->value ); } /** * 测试验证物品 - 物品没有对应属性 */ public function testValidateItemWithoutAttribute() { $reflection = new \ReflectionClass(DisasterRemovalLogic::class); $validateItemMethod = $reflection->getMethod('validateItem'); $validateItemMethod->setAccessible(true); // Mock ItemService $this->mock(ItemService::class, function ($mock) { $mock->shouldReceive('getUserItems') ->with(1, ['item_id' => 123]) ->andReturn(collect([new \stdClass()])); // 有物品 $mock->shouldReceive('getItemNumericAttribute') ->with(123, 'fram_pesticide_rate') ->andReturn(0); // 没有对应属性或属性值为0 }); $this->expectException(LogicException::class); $this->expectExceptionMessage('不是除虫物品'); $validateItemMethod->invoke( $this->disasterRemovalLogic, 1, // userId 123, // itemId DISASTER_TYPE::PEST->value ); } }