id = 1; $petDataDto->typeId = 1; $petDataDto->name = '测试宠物'; $petDataDto->level = 5; $petDataDto->exp = 100; $petDataDto->power = 80; $petDataDto->maxpower = 100; $petDataDto->score = 150; $petDataDto->fightingCapacity = 150; $petDataDto->grade = 2; $petDataDto->status = 1; // 创建生活技能数据 $lifeSkill1 = new PetLifeSkillDto(); $lifeSkill1->skillId = 1; $lifeSkill1->canuse = true; $lifeSkill1->curnum = 0; $lifeSkill1->maxnum = 300; $lifeSkill2 = new PetLifeSkillDto(); $lifeSkill2->skillId = 2; $lifeSkill2->canuse = false; $lifeSkill2->curnum = 150; $lifeSkill2->maxnum = 300; $petDataDto->lifeSkills = [$lifeSkill1, $lifeSkill2]; // Mock PetService::getPetStatus 方法 $this->mock(PetService::class, function ($mock) use ($petDataDto) { $mock->shouldReceive('getPetStatus') ->with(10001, 1) ->andReturn($petDataDto); }); // 创建宠物技能使用事件 $event = new PetSkillUsedEvent(10001, 1, 1, []); // 创建监听器并处理事件 $listener = new PetSkillUsedListener(); $listener->handle($event); // 验证数据是否正确存储到临时缓存 $petUpdates = PetTemp::getUserPetUpdates(10001); $this->assertNotEmpty($petUpdates, '宠物更新数据应该不为空'); $this->assertArrayHasKey(1, $petUpdates, '应该包含宠物ID为1的数据'); $petTempDto = $petUpdates[1]; $this->assertInstanceOf(PetStatusTempDto::class, $petTempDto, '应该是PetStatusTempDto实例'); // 验证基本属性 $this->assertEquals(1, $petTempDto->id); $this->assertEquals('测试宠物', $petTempDto->name); $this->assertEquals(5, $petTempDto->level); $this->assertEquals(80, $petTempDto->power); // 验证生活技能数据 $this->assertIsArray($petTempDto->lifeSkills, 'lifeSkills应该是数组'); $this->assertCount(2, $petTempDto->lifeSkills, '应该有2个生活技能'); // 验证第一个技能 $skill1 = $petTempDto->lifeSkills[0]; $this->assertInstanceOf(PetLifeSkillDto::class, $skill1, '技能应该是PetLifeSkillDto实例'); $this->assertEquals(1, $skill1->skillId); $this->assertTrue($skill1->canuse); $this->assertEquals(0, $skill1->curnum); $this->assertEquals(300, $skill1->maxnum); // 验证第二个技能 $skill2 = $petTempDto->lifeSkills[1]; $this->assertInstanceOf(PetLifeSkillDto::class, $skill2, '技能应该是PetLifeSkillDto实例'); $this->assertEquals(2, $skill2->skillId); $this->assertFalse($skill2->canuse); $this->assertEquals(150, $skill2->curnum); $this->assertEquals(300, $skill2->maxnum); } /** * 测试从缓存恢复数据时lifeSkills的正确性 */ public function test_pet_status_temp_dto_from_cache() { // 模拟缓存中的数据(数组格式) $cachedData = [ 1 => [ 'id' => 1, 'type_id' => 1, 'name' => '测试宠物', 'level' => 5, 'exp' => 100, 'power' => 80, 'maxpower' => 100, 'score' => 150, 'fighting_capacity' => 150, 'grade' => 2, 'status' => 1, 'life_skills' => [ [ 'skill_id' => 1, 'canuse' => true, 'curnum' => 0, 'maxnum' => 300 ], [ 'skill_id' => 2, 'canuse' => false, 'curnum' => 150, 'maxnum' => 300 ] ], 'updated_at' => time() ] ]; // 使用fromCache方法恢复数据 $result = PetStatusTempDto::fromCache($cachedData); $this->assertNotEmpty($result, '恢复的数据应该不为空'); $this->assertArrayHasKey(1, $result, '应该包含宠物ID为1的数据'); $petDto = $result[1]; $this->assertInstanceOf(PetStatusTempDto::class, $petDto, '应该是PetStatusTempDto实例'); // 验证基本属性 $this->assertEquals(1, $petDto->id); $this->assertEquals('测试宠物', $petDto->name); $this->assertEquals(5, $petDto->level); $this->assertEquals(80, $petDto->power); // 验证生活技能数据 $this->assertIsArray($petDto->lifeSkills, 'lifeSkills应该是数组'); $this->assertCount(2, $petDto->lifeSkills, '应该有2个生活技能'); // 验证第一个技能 $skill1 = $petDto->lifeSkills[0]; $this->assertInstanceOf(PetLifeSkillDto::class, $skill1, '技能应该是PetLifeSkillDto实例'); $this->assertEquals(1, $skill1->skillId); $this->assertTrue($skill1->canuse); $this->assertEquals(0, $skill1->curnum); $this->assertEquals(300, $skill1->maxnum); // 验证第二个技能 $skill2 = $petDto->lifeSkills[1]; $this->assertInstanceOf(PetLifeSkillDto::class, $skill2, '技能应该是PetLifeSkillDto实例'); $this->assertEquals(2, $skill2->skillId); $this->assertFalse($skill2->canuse); $this->assertEquals(150, $skill2->curnum); $this->assertEquals(300, $skill2->maxnum); } /** * 测试AppGameProtobufResponseListener处理宠物数据时不会出错 */ public function test_app_game_protobuf_response_listener_handles_pet_data() { // 创建测试用的宠物数据并存储到临时缓存 $petTempDto = new PetStatusTempDto(); $petTempDto->id = 1; $petTempDto->typeId = 1; $petTempDto->name = '测试宠物'; $petTempDto->level = 5; $petTempDto->exp = 100; $petTempDto->power = 80; $petTempDto->maxpower = 100; $petTempDto->score = 150; $petTempDto->fightingCapacity = 150; $petTempDto->grade = 2; $petTempDto->status = 1; // 创建生活技能数据 $lifeSkill1 = new PetLifeSkillDto(); $lifeSkill1->skillId = 1; $lifeSkill1->canuse = true; $lifeSkill1->curnum = 0; $lifeSkill1->maxnum = 300; $lifeSkill2 = new PetLifeSkillDto(); $lifeSkill2->skillId = 2; $lifeSkill2->canuse = false; $lifeSkill2->curnum = 150; $lifeSkill2->maxnum = 300; $petTempDto->lifeSkills = [$lifeSkill1, $lifeSkill2]; $petTempDto->updatedAt = time(); // 手动存储到缓存 $tempKey = 'pet_temp_update_10001'; Cache::put($tempKey, [1 => $petTempDto], 3600); // 获取数据并验证 $petUpdates = PetTemp::getUserPetUpdates(10001); $this->assertNotEmpty($petUpdates, '宠物更新数据应该不为空'); $this->assertArrayHasKey(1, $petUpdates, '应该包含宠物ID为1的数据'); $retrievedPet = $petUpdates[1]; $this->assertInstanceOf(PetStatusTempDto::class, $retrievedPet, '应该是PetStatusTempDto实例'); // 验证生活技能数据类型正确 $this->assertIsArray($retrievedPet->lifeSkills, 'lifeSkills应该是数组'); $this->assertCount(2, $retrievedPet->lifeSkills, '应该有2个生活技能'); foreach ($retrievedPet->lifeSkills as $skill) { $this->assertInstanceOf(PetLifeSkillDto::class, $skill, '每个技能都应该是PetLifeSkillDto实例'); $this->assertObjectHasProperty('skillId', $skill, '技能应该有skillId属性'); $this->assertObjectHasProperty('canuse', $skill, '技能应该有canuse属性'); $this->assertObjectHasProperty('curnum', $skill, '技能应该有curnum属性'); $this->assertObjectHasProperty('maxnum', $skill, '技能应该有maxnum属性'); } } }