diff --git a/tests/langsmith_tracing/conftest.py b/tests/langsmith_tracing/conftest.py new file mode 100644 index 00000000..d66384f8 --- /dev/null +++ b/tests/langsmith_tracing/conftest.py @@ -0,0 +1,21 @@ +"""Shared fixtures for LangSmith tracing tests.""" + +from unittest.mock import MagicMock + +import pytest + + +@pytest.fixture +def mock_ls_client() -> MagicMock: + """Return a mock ``langsmith.Client`` that never makes network calls. + + The samples tests don't assert on trace output — the LangSmith plugin + just needs *some* client object to wire into the worker. ``MagicMock`` + auto-stubs every method the interceptor calls; the explicit ``session`` + and ``tracing_queue`` stubs match what the langsmith library touches + internally. + """ + client = MagicMock() + client.session = MagicMock() + client.tracing_queue = MagicMock() + return client diff --git a/tests/langsmith_tracing/test_basic.py b/tests/langsmith_tracing/test_basic.py index b5be2f35..cef49054 100644 --- a/tests/langsmith_tracing/test_basic.py +++ b/tests/langsmith_tracing/test_basic.py @@ -1,4 +1,5 @@ import uuid +from unittest.mock import MagicMock from temporalio import activity from temporalio.client import Client @@ -10,7 +11,9 @@ from langsmith_tracing.basic.workflows import BasicLLMWorkflow -async def test_basic_workflow(client: Client, env: WorkflowEnvironment): +async def test_basic_workflow( + client: Client, env: WorkflowEnvironment, mock_ls_client: MagicMock +): expected_text = "Temporal is a durable execution platform." @activity.defn(name="call_openai") @@ -22,7 +25,7 @@ async def mock_call_openai(request: OpenAIRequest) -> str: task_queue="test-langsmith-basic", workflows=[BasicLLMWorkflow], activities=[mock_call_openai], - plugins=[LangSmithPlugin()], + plugins=[LangSmithPlugin(client=mock_ls_client)], ): result = await client.execute_workflow( BasicLLMWorkflow.run, diff --git a/tests/langsmith_tracing/test_chatbot.py b/tests/langsmith_tracing/test_chatbot.py index 2febb654..88d98202 100644 --- a/tests/langsmith_tracing/test_chatbot.py +++ b/tests/langsmith_tracing/test_chatbot.py @@ -1,5 +1,6 @@ import json import uuid +from unittest.mock import MagicMock from temporalio import activity from temporalio.client import Client @@ -27,7 +28,9 @@ def _make_function_call_response( ) -async def test_chatbot_save_note(client: Client, env: WorkflowEnvironment): +async def test_chatbot_save_note( + client: Client, env: WorkflowEnvironment, mock_ls_client: MagicMock +): """Test save_note tool call loop — save_note runs as a workflow method.""" call_count = 0 @@ -47,7 +50,7 @@ async def mock_call_openai(request: OpenAIRequest) -> ChatResponse: task_queue="test-langsmith-chatbot", workflows=[ChatbotWorkflow], activities=[mock_call_openai], - plugins=[LangSmithPlugin()], + plugins=[LangSmithPlugin(client=mock_ls_client)], ): wf_handle = await client.start_workflow( ChatbotWorkflow.run, @@ -68,8 +71,10 @@ async def mock_call_openai(request: OpenAIRequest) -> ChatResponse: assert result == "Session ended." -async def test_chatbot_read_note(client: Client, env: WorkflowEnvironment): - """Test read_note tool call loop — read_note runs as a workflow method.""" +async def test_chatbot_read_note( + client: Client, env: WorkflowEnvironment, mock_ls_client: MagicMock +): + """Test read_note tool call loop — saves a note first, then reads it back.""" call_count = 0 @activity.defn(name="call_openai") @@ -97,7 +102,7 @@ async def mock_call_openai(request: OpenAIRequest) -> ChatResponse: task_queue="test-langsmith-chatbot-read", workflows=[ChatbotWorkflow], activities=[mock_call_openai], - plugins=[LangSmithPlugin()], + plugins=[LangSmithPlugin(client=mock_ls_client)], ): wf_handle = await client.start_workflow( ChatbotWorkflow.run,