fix: Add sys.modules stub fixture for mcp modules in tests

- Add autouse fixture to stub mcp, mcp.client, and mcp.client.streamable_http modules
- Revert patch targets to module-local names (crewai.tools.mcp_tool_wrapper.*)
- This fixes ModuleNotFoundError in CI where mcp package is not installed
- The stub fixture ensures tests can run without requiring the actual mcp package

Co-Authored-By: João <joao@crewai.com>
This commit is contained in:
Devin AI
2025-10-26 09:58:46 +00:00
parent 99418b1160
commit 3b77dd57d8

View File

@@ -1,6 +1,8 @@
"""Tests for MCPToolWrapper progress and headers support.""" """Tests for MCPToolWrapper progress and headers support."""
import asyncio import asyncio
import sys
import types
from unittest.mock import AsyncMock, MagicMock, Mock, patch from unittest.mock import AsyncMock, MagicMock, Mock, patch
import pytest import pytest
@@ -10,6 +12,33 @@ from crewai.events.types.tool_usage_events import MCPToolProgressEvent
from crewai.tools.mcp_tool_wrapper import MCPToolWrapper from crewai.tools.mcp_tool_wrapper import MCPToolWrapper
@pytest.fixture(autouse=True)
def stub_mcp_modules(monkeypatch):
"""Stub the mcp modules in sys.modules to avoid import errors in CI."""
mcp = types.ModuleType("mcp")
mcp_client = types.ModuleType("mcp.client")
mcp_streamable_http = types.ModuleType("mcp.client.streamable_http")
mcp.ClientSession = MagicMock()
async def fake_streamablehttp_client(*args, **kwargs):
"""Mock streamablehttp_client context manager."""
class MockContextManager:
async def __aenter__(self):
return (AsyncMock(), AsyncMock(), AsyncMock())
async def __aexit__(self, *exc):
pass
return MockContextManager()
mcp_streamable_http.streamablehttp_client = fake_streamablehttp_client
monkeypatch.setitem(sys.modules, "mcp", mcp)
monkeypatch.setitem(sys.modules, "mcp.client", mcp_client)
monkeypatch.setitem(sys.modules, "mcp.client.streamable_http", mcp_streamable_http)
@pytest.fixture @pytest.fixture
def mock_mcp_session(): def mock_mcp_session():
"""Create a mock MCP ClientSession.""" """Create a mock MCP ClientSession."""
@@ -119,8 +148,8 @@ class TestMCPToolWrapperProgress:
mock_result = Mock() mock_result = Mock()
mock_result.content = [Mock(text="Test result")] mock_result.content = [Mock(text="Test result")]
with patch("mcp.client.streamable_http.streamablehttp_client") as mock_client, \ with patch("crewai.tools.mcp_tool_wrapper.streamablehttp_client") as mock_client, \
patch("mcp.ClientSession") as mock_session_class: patch("crewai.tools.mcp_tool_wrapper.ClientSession") as mock_session_class:
mock_session = AsyncMock() mock_session = AsyncMock()
mock_session.initialize = AsyncMock() mock_session.initialize = AsyncMock()
@@ -243,8 +272,8 @@ class TestMCPToolWrapperHeaders:
mock_result = Mock() mock_result = Mock()
mock_result.content = [Mock(text="Test result")] mock_result.content = [Mock(text="Test result")]
with patch("mcp.client.streamable_http.streamablehttp_client") as mock_client, \ with patch("crewai.tools.mcp_tool_wrapper.streamablehttp_client") as mock_client, \
patch("mcp.ClientSession") as mock_session_class: patch("crewai.tools.mcp_tool_wrapper.ClientSession") as mock_session_class:
mock_session = AsyncMock() mock_session = AsyncMock()
mock_session.initialize = AsyncMock() mock_session.initialize = AsyncMock()
@@ -277,8 +306,8 @@ class TestMCPToolWrapperHeaders:
mock_result = Mock() mock_result = Mock()
mock_result.content = [Mock(text="Test result")] mock_result.content = [Mock(text="Test result")]
with patch("mcp.client.streamable_http.streamablehttp_client") as mock_client, \ with patch("crewai.tools.mcp_tool_wrapper.streamablehttp_client") as mock_client, \
patch("mcp.ClientSession") as mock_session_class: patch("crewai.tools.mcp_tool_wrapper.ClientSession") as mock_session_class:
mock_session = AsyncMock() mock_session = AsyncMock()
mock_session.initialize = AsyncMock() mock_session.initialize = AsyncMock()
@@ -326,8 +355,8 @@ class TestMCPToolWrapperIntegration:
mock_result = Mock() mock_result = Mock()
mock_result.content = [Mock(text="Test result")] mock_result.content = [Mock(text="Test result")]
with patch("mcp.client.streamable_http.streamablehttp_client") as mock_client, \ with patch("crewai.tools.mcp_tool_wrapper.streamablehttp_client") as mock_client, \
patch("mcp.ClientSession") as mock_session_class: patch("crewai.tools.mcp_tool_wrapper.ClientSession") as mock_session_class:
mock_session = AsyncMock() mock_session = AsyncMock()
mock_session.initialize = AsyncMock() mock_session.initialize = AsyncMock()