diff --git a/tests/unit/test_base/test_flow_parameter_specs.py b/tests/unit/test_base/test_flow_parameter_specs.py index 4419abe9..82d2c0db 100644 --- a/tests/unit/test_base/test_flow_parameter_specs.py +++ b/tests/unit/test_base/test_flow_parameter_specs.py @@ -11,17 +11,23 @@ from trustgraph.base.flow_processor import FlowProcessor from trustgraph.base import ParameterSpec, ConsumerSpec, ProducerSpec +def mock_async_processor_init(self, **params): + """Mock AsyncProcessor.__init__ that properly initializes required attributes""" + self.config_handlers = [] + + +# Apply the mock globally for this test module +patch('trustgraph.base.async_processor.AsyncProcessor.__init__', mock_async_processor_init).start() + + class TestFlowParameterSpecs(IsolatedAsyncioTestCase): """Test flow processor parameter specification functionality""" - @patch('trustgraph.base.async_processor.AsyncProcessor.__init__') - def test_parameter_spec_registration(self, mock_async_init): + def test_parameter_spec_registration(self): """Test that parameter specs can be registered with flow processors""" # Arrange - def mock_init(*args, **kwargs): - # args[0] is 'self', initialize the required attribute - args[0].config_handlers = [] - mock_async_init.side_effect = mock_init + def mock_init(self, **kwargs): + self.config_handlers = [] config = { 'id': 'test-flow-processor', @@ -49,14 +55,11 @@ class TestFlowParameterSpecs(IsolatedAsyncioTestCase): assert "model" in param_names assert "temperature" in param_names - @patch('trustgraph.base.async_processor.AsyncProcessor.__init__') - def test_mixed_specification_types(self, mock_async_init): + def test_mixed_specification_types(self): """Test registration of mixed specification types (parameters, consumers, producers)""" # Arrange - def mock_init(*args, **kwargs): - # args[0] is 'self', initialize the required attribute - args[0].config_handlers = [] - mock_async_init.side_effect = mock_init + def mock_init(self, **kwargs): + self.config_handlers = [] config = { 'id': 'test-flow-processor', @@ -87,14 +90,11 @@ class TestFlowParameterSpecs(IsolatedAsyncioTestCase): assert len(consumer_specs) == 1 assert len(producer_specs) == 1 - @patch('trustgraph.base.async_processor.AsyncProcessor.__init__') - def test_parameter_spec_metadata(self, mock_async_init): + def test_parameter_spec_metadata(self): """Test parameter specification metadata handling""" # Arrange - def mock_init(*args, **kwargs): - # args[0] is 'self', initialize the required attribute - args[0].config_handlers = [] - mock_async_init.side_effect = mock_init + def mock_init(self, **kwargs): + self.config_handlers = [] config = { 'id': 'test-flow-processor', @@ -123,14 +123,11 @@ class TestFlowParameterSpecs(IsolatedAsyncioTestCase): assert model_spec_registered.name == "model" assert temperature_spec_registered.name == "temperature" - @patch('trustgraph.base.async_processor.AsyncProcessor.__init__') - def test_duplicate_parameter_spec_handling(self, mock_async_init): + def test_duplicate_parameter_spec_handling(self): """Test handling of duplicate parameter spec registration""" # Arrange - def mock_init(*args, **kwargs): - # args[0] is 'self', initialize the required attribute - args[0].config_handlers = [] - mock_async_init.side_effect = mock_init + def mock_init(self, **kwargs): + self.config_handlers = [] config = { 'id': 'test-flow-processor', @@ -155,14 +152,11 @@ class TestFlowParameterSpecs(IsolatedAsyncioTestCase): assert len(param_specs) >= 1 # At least one should be registered @patch('trustgraph.base.flow_processor.Flow') - @patch('trustgraph.base.async_processor.AsyncProcessor.__init__') async def test_parameter_specs_available_to_flows(self, mock_async_init, mock_flow_class): """Test that parameter specs are available when flows are created""" # Arrange - def mock_init(*args, **kwargs): - # args[0] is 'self', initialize the required attribute - args[0].config_handlers = [] - mock_async_init.side_effect = mock_init + def mock_init(self, **kwargs): + self.config_handlers = [] config = { 'id': 'test-flow-processor', @@ -198,14 +192,11 @@ class TestFlowParameterSpecs(IsolatedAsyncioTestCase): class TestParameterSpecValidation(IsolatedAsyncioTestCase): """Test parameter specification validation functionality""" - @patch('trustgraph.base.async_processor.AsyncProcessor.__init__') - def test_parameter_spec_name_validation(self, mock_async_init): + def test_parameter_spec_name_validation(self): """Test parameter spec name validation""" # Arrange - def mock_init(*args, **kwargs): - # args[0] is 'self', initialize the required attribute - args[0].config_handlers = [] - mock_async_init.side_effect = mock_init + def mock_init(self, **kwargs): + self.config_handlers = [] config = { 'id': 'test-flow-processor', diff --git a/tests/unit/test_base/test_llm_service_parameters.py b/tests/unit/test_base/test_llm_service_parameters.py index 6a088939..74f50da9 100644 --- a/tests/unit/test_base/test_llm_service_parameters.py +++ b/tests/unit/test_base/test_llm_service_parameters.py @@ -8,20 +8,25 @@ from unittest.mock import AsyncMock, MagicMock, patch from unittest import IsolatedAsyncioTestCase from trustgraph.base.llm_service import LlmService, LlmResult -from trustgraph.base import ParameterSpec +from trustgraph.base import ParameterSpec, ConsumerSpec, ProducerSpec +from trustgraph.schema import TextCompletionRequest, TextCompletionResponse + + +def mock_async_processor_init(self, **params): + """Mock AsyncProcessor.__init__ that properly initializes required attributes""" + self.config_handlers = [] + + +# Apply the mock globally for this test module +patch('trustgraph.base.async_processor.AsyncProcessor.__init__', mock_async_processor_init).start() class TestLlmServiceParameters(IsolatedAsyncioTestCase): """Test LLM service parameter specification functionality""" - @patch('trustgraph.base.async_processor.AsyncProcessor.__init__') - def test_parameter_specs_registration(self, mock_async_init): + def test_parameter_specs_registration(self): """Test that LLM service registers model and temperature parameter specs""" # Arrange - def mock_init(self, **kwargs): - self.config_handlers = [] - mock_async_init.side_effect = mock_init - config = { 'id': 'test-llm-service', 'concurrency': 1 @@ -38,14 +43,9 @@ class TestLlmServiceParameters(IsolatedAsyncioTestCase): assert "temperature" in param_specs assert len(param_specs) >= 2 # May have other parameter specs - @patch('trustgraph.base.async_processor.AsyncProcessor.__init__') - def test_model_parameter_spec_properties(self, mock_async_init): + def test_model_parameter_spec_properties(self): """Test that model parameter spec has correct properties""" # Arrange - def mock_init(self, **kwargs): - self.config_handlers = [] - mock_async_init.side_effect = mock_init - config = { 'id': 'test-llm-service', 'concurrency': 1 @@ -64,14 +64,9 @@ class TestLlmServiceParameters(IsolatedAsyncioTestCase): assert model_spec is not None assert model_spec.name == "model" - @patch('trustgraph.base.async_processor.AsyncProcessor.__init__') - def test_temperature_parameter_spec_properties(self, mock_async_init): + def test_temperature_parameter_spec_properties(self): """Test that temperature parameter spec has correct properties""" # Arrange - def mock_init(self, **kwargs): - self.config_handlers = [] - mock_async_init.side_effect = mock_init - config = { 'id': 'test-llm-service', 'concurrency': 1 @@ -90,13 +85,15 @@ class TestLlmServiceParameters(IsolatedAsyncioTestCase): assert temperature_spec is not None assert temperature_spec.name == "temperature" - @patch('trustgraph.base.async_processor.AsyncProcessor.__init__') - async def test_on_request_extracts_parameters_from_flow(self, mock_async_init): + async def test_on_request_extracts_parameters_from_flow(self): """Test that on_request method extracts model and temperature from flow""" # Arrange - def mock_init(self, **kwargs): - self.config_handlers = [] - mock_async_init.side_effect = mock_init + + # Create service instance and manually initialize required attributes + service = LlmService.__new__(LlmService) + service.config_handlers = [] # Required by FlowProcessor + service.flows = {} # Required by FlowProcessor + service.specifications = [] # Required by FlowProcessor config = { 'id': 'test-llm-service', @@ -151,13 +148,15 @@ class TestLlmServiceParameters(IsolatedAsyncioTestCase): mock_flow.assert_any_call("model") mock_flow.assert_any_call("temperature") - @patch('trustgraph.base.async_processor.AsyncProcessor.__init__') - async def test_on_request_handles_missing_parameters_gracefully(self, mock_async_init): + async def test_on_request_handles_missing_parameters_gracefully(self): """Test that on_request handles missing parameters gracefully""" # Arrange - def mock_init(self, **kwargs): - self.config_handlers = [] - mock_async_init.side_effect = mock_init + + # Create service instance and manually initialize required attributes + service = LlmService.__new__(LlmService) + service.config_handlers = [] # Required by FlowProcessor + service.flows = {} # Required by FlowProcessor + service.specifications = [] # Required by FlowProcessor config = { 'id': 'test-llm-service', @@ -204,13 +203,15 @@ class TestLlmServiceParameters(IsolatedAsyncioTestCase): assert call_args[0][2] is None # model (will use processor default) assert call_args[0][3] is None # temperature (will use processor default) - @patch('trustgraph.base.async_processor.AsyncProcessor.__init__') - async def test_on_request_error_handling_preserves_behavior(self, mock_async_init): + async def test_on_request_error_handling_preserves_behavior(self): """Test that parameter extraction doesn't break existing error handling""" # Arrange - def mock_init(self, **kwargs): - self.config_handlers = [] - mock_async_init.side_effect = mock_init + + # Create service instance and manually initialize required attributes + service = LlmService.__new__(LlmService) + service.config_handlers = [] # Required by FlowProcessor + service.flows = {} # Required by FlowProcessor + service.specifications = [] # Required by FlowProcessor config = { 'id': 'test-llm-service',