1+ import pytest
2+ from unittest .mock import patch , AsyncMock
3+
4+ from backend .agents .agent_factory import AgentFactory
5+
6+
7+ class TestAgentFactory :
8+ """Test suite for AgentFactory class."""
9+
10+ @pytest .fixture
11+ def reset_singleton (self ):
12+ """Fixture to reset the singleton between tests"""
13+ original_instance = AgentFactory ._instance
14+ AgentFactory ._instance = None
15+ yield
16+ AgentFactory ._instance = original_instance
17+
18+ @pytest .mark .asyncio
19+ @patch ("backend.agents.agent_factory.AzureAIAgent" )
20+ @patch ("backend.agents.agent_factory.DefaultAzureCredential" )
21+ @patch ("backend.agents.agent_factory.AzureAIAgentSettings" )
22+ async def test_get_instance_creates_agent_when_none_exists (
23+ self , mock_settings , mock_credential , mock_agent , reset_singleton
24+ ):
25+ """Test that get_instance creates a new agent when none exists."""
26+ # Arrange
27+ mock_agent_instance = AsyncMock ()
28+ mock_agent .return_value = mock_agent_instance
29+ mock_client = AsyncMock ()
30+ mock_agent .create_client .return_value = mock_client
31+
32+ # Act
33+ result = await AgentFactory .get_instance ()
34+
35+ # Assert
36+ assert result is not None
37+ assert AgentFactory ._instance is not None
38+ assert AgentFactory ._instance is result
39+ assert mock_agent .create_client .called
40+ assert mock_agent .called
41+
42+ @pytest .mark .asyncio
43+ async def test_get_instance_returns_existing_agent (self , reset_singleton ):
44+ """Test that get_instance returns existing agent when one exists."""
45+ # Arrange
46+ mock_instance = AsyncMock ()
47+ AgentFactory ._instance = mock_instance
48+
49+ # Act
50+ result = await AgentFactory .get_instance ()
51+
52+ # Assert
53+ assert result is mock_instance
54+
55+ @pytest .mark .asyncio
56+ async def test_multiple_calls_return_same_instance (self , reset_singleton ):
57+ """Test that multiple calls to get_instance return the same instance."""
58+ # Arrange
59+ mock_agent = AsyncMock ()
60+ mock_client = AsyncMock ()
61+ mock_agent_definition = AsyncMock ()
62+ mock_agent_instance = AsyncMock ()
63+
64+ with patch ("backend.agents.agent_factory.AzureAIAgent" ) as mock_agent_class :
65+ mock_agent_class .create_client .return_value = mock_client
66+ mock_client .agents .create_agent = AsyncMock (return_value = mock_agent_definition )
67+ mock_agent_class .return_value = mock_agent_instance
68+
69+ with patch ("backend.agents.agent_factory.DefaultAzureCredential" ):
70+ with patch ("backend.agents.agent_factory.AzureAIAgentSettings" ):
71+ # Act
72+ instance1 = await AgentFactory .get_instance ()
73+ instance2 = await AgentFactory .get_instance ()
74+
75+ # Assert
76+ assert instance1 is instance2
77+
78+ @pytest .mark .asyncio
79+ async def test_delete_instance_when_none_exists (self , reset_singleton ):
80+ """Test that delete_instance handles when no agent exists."""
81+ # Arrange
82+ AgentFactory ._instance = None
83+
84+ # Act
85+ await AgentFactory .delete_instance ()
86+
87+ # Assert
88+ assert AgentFactory ._instance is None
89+
90+ @pytest .mark .asyncio
91+ async def test_delete_instance_removes_existing_agent (self , reset_singleton ):
92+ """Test that delete_instance properly removes an existing agent."""
93+ # Arrange
94+ mock_agent = AsyncMock ()
95+ mock_agent .client = AsyncMock ()
96+ mock_agent .id = "test-agent-id"
97+ AgentFactory ._instance = mock_agent
98+
99+ # Act
100+ await AgentFactory .delete_instance ()
101+
102+ # Assert
103+ assert AgentFactory ._instance is None
104+ mock_agent .client .agents .delete_agent .assert_called_once_with (mock_agent .id )
0 commit comments