Skip to content

Commit 3c555e2

Browse files
feat: enhance agent framework mocking and patch missing Azure AI project models
1 parent a9e7c16 commit 3c555e2

1 file changed

Lines changed: 73 additions & 6 deletions

File tree

src/tests/backend/conftest.py

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,60 @@ def _setup_agent_framework_mock():
4242
"""
4343
Set up mock for agent_framework which is not a pip-installable package.
4444
This framework is used for Azure AI Agents and needs proper mocking.
45+
Uses ModuleType with real stub classes for names used in type annotations
46+
or as base classes, and MagicMock for everything else.
4547
"""
4648
if 'agent_framework' not in sys.modules:
47-
# Use MagicMock so any attribute access (ChatAgent, ChatMessage, etc.) works
48-
mock_af = MagicMock()
49-
49+
# Top-level: agent_framework
50+
mock_af = ModuleType('agent_framework')
51+
52+
# Names used as base classes or in Union type hints MUST be real classes
53+
# to avoid SyntaxError from typing module's forward reference evaluation.
54+
_class_names = [
55+
'AgentResponse', 'AgentResponseUpdate', 'AgentRunUpdateEvent',
56+
'AgentThread', 'BaseAgent', 'ChatAgent', 'ChatMessage',
57+
'ChatOptions', 'Content', 'ExecutorCompletedEvent',
58+
'GroupChatRequestSentEvent', 'GroupChatResponseReceivedEvent',
59+
'HostedCodeInterpreterTool', 'HostedMCPTool',
60+
'InMemoryCheckpointStorage', 'MCPStreamableHTTPTool',
61+
'MagenticBuilder', 'MagenticOrchestratorEvent',
62+
'MagenticProgressLedger', 'Role', 'UsageDetails',
63+
'WorkflowOutputEvent',
64+
]
65+
for name in _class_names:
66+
setattr(mock_af, name, type(name, (), {}))
67+
68+
# Sub-module: agent_framework.azure
69+
mock_af_azure = ModuleType('agent_framework.azure')
70+
mock_af_azure.AzureOpenAIChatClient = type('AzureOpenAIChatClient', (), {})
71+
mock_af.azure = mock_af_azure
72+
73+
# Sub-module: agent_framework._workflows._magentic
74+
mock_af_workflows = ModuleType('agent_framework._workflows')
75+
mock_af_magentic = ModuleType('agent_framework._workflows._magentic')
76+
for name in [
77+
'MagenticContext', 'StandardMagenticManager',
78+
]:
79+
setattr(mock_af_magentic, name, type(name, (), {}))
80+
for name in [
81+
'ORCHESTRATOR_FINAL_ANSWER_PROMPT',
82+
'ORCHESTRATOR_PROGRESS_LEDGER_PROMPT',
83+
'ORCHESTRATOR_TASK_LEDGER_PLAN_PROMPT',
84+
'ORCHESTRATOR_TASK_LEDGER_PLAN_UPDATE_PROMPT',
85+
]:
86+
setattr(mock_af_magentic, name, "mock_prompt_string")
87+
mock_af_workflows._magentic = mock_af_magentic
88+
mock_af._workflows = mock_af_workflows
89+
5090
sys.modules['agent_framework'] = mock_af
51-
sys.modules['agent_framework.azure'] = mock_af.azure
52-
91+
sys.modules['agent_framework.azure'] = mock_af_azure
92+
sys.modules['agent_framework._workflows'] = mock_af_workflows
93+
sys.modules['agent_framework._workflows._magentic'] = mock_af_magentic
94+
5395
if 'agent_framework_azure_ai' not in sys.modules:
54-
sys.modules['agent_framework_azure_ai'] = MagicMock()
96+
mock_af_ai = ModuleType('agent_framework_azure_ai')
97+
mock_af_ai.AzureAIClient = type('AzureAIClient', (), {})
98+
sys.modules['agent_framework_azure_ai'] = mock_af_ai
5599

56100

57101
def _setup_azure_monitor_mock():
@@ -62,10 +106,33 @@ def _setup_azure_monitor_mock():
62106
sys.modules['azure.monitor.opentelemetry'] = mock_module
63107

64108

109+
def _patch_azure_ai_projects_models():
110+
"""
111+
Patch azure.ai.projects.models to add names that may be missing
112+
in older SDK versions (e.g. PromptAgentDefinition).
113+
"""
114+
try:
115+
import azure.ai.projects.models as models_mod
116+
missing_names = [
117+
'PromptAgentDefinition',
118+
'AzureAISearchAgentTool',
119+
'AzureAISearchToolResource',
120+
'AISearchIndexResource',
121+
]
122+
for name in missing_names:
123+
if not hasattr(models_mod, name):
124+
setattr(models_mod, name, MagicMock())
125+
except ImportError:
126+
# azure-ai-projects not installed at all — create full mock
127+
sys.modules['azure.ai.projects'] = MagicMock()
128+
sys.modules['azure.ai.projects.models'] = MagicMock()
129+
130+
65131
# Set up environment and minimal mocks before any test imports
66132
_setup_environment_variables()
67133
_setup_agent_framework_mock()
68134
_setup_azure_monitor_mock()
135+
_patch_azure_ai_projects_models()
69136

70137

71138
@pytest.fixture

0 commit comments

Comments
 (0)