Files
cultivation-world-simulator/tests/test_action_social.py
2025-12-20 17:13:53 +08:00

81 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pytest
from unittest.mock import MagicMock, patch, AsyncMock
from src.classes.mutual_action.conversation import Conversation
from src.classes.action_runtime import ActionStatus
from src.classes.event import Event
class TestActionSocial:
@pytest.fixture
def target_avatar(self, dummy_avatar):
target = MagicMock()
target.name = "FriendDummy"
target.id = "friend_id"
target.get_info.return_value = "Target Info"
target.get_planned_actions_str.return_value = "None"
target.thinking = ""
# 模拟 add_event
target.events = []
target.add_event = lambda e, to_sidebar=False: target.events.append(e)
# 模拟修炼进度(用于关系判断)
target.cultivation_progress.level = 10
target.gender = dummy_avatar.gender # 同性
target.get_relation.return_value = None
return target
@pytest.mark.asyncio
@patch("src.classes.mutual_action.mutual_action.call_llm_with_template", new_callable=AsyncMock)
async def test_conversation_flow(self, mock_llm, dummy_avatar, target_avatar):
"""测试对话流程Step -> LLM -> Feedback"""
# 1. 准备 Mock LLM 返回
mock_response = {
"FriendDummy": {
"thinking": "He is nice.",
"conversation_content": "Hello there!",
"feedback": "Accept" # Conversation 其实不强制 feedback主要是 content
}
}
mock_llm.return_value = mock_response
# 注入 World 查找
dummy_avatar.world.avatar_manager.avatars = {target_avatar.name: target_avatar}
# Mock 自己的 level (避免 dummy_avatar 中也是 Mock 导致无法比较)
dummy_avatar.cultivation_progress.level = 10
# 2. 初始化 Action
action = Conversation(dummy_avatar, dummy_avatar.world)
action._start_month_stamp = 100
# 3. 第一次 Step: 应该触发 LLM 任务并返回 RUNNING
res1 = action.step(target_avatar=target_avatar)
assert res1.status == ActionStatus.RUNNING
assert action._feedback_task is not None
# 等待 Task 完成
await action._feedback_task
# 4. 第二次 Step: 消费结果
res2 = action.step(target_avatar=target_avatar)
assert res2.status == ActionStatus.COMPLETED
# 5. 验证结果
# 应该有一个包含对话内容的事件
assert len(res2.events) >= 1
content_event = res2.events[0]
assert "Hello there!" in content_event.content
assert dummy_avatar.id in content_event.related_avatars
assert target_avatar.id in content_event.related_avatars
# 验证 Target 思考被更新
assert target_avatar.thinking == "He is nice."
def test_conversation_no_target(self, dummy_avatar):
action = Conversation(dummy_avatar, dummy_avatar.world)
res = action.step(target_avatar=None)
assert res.status == ActionStatus.FAILED