mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-08 22:21:35 +00:00
fix(test_resend_email): use direct mock injection for all email tests
Extend the mock injection pattern used in test_send_email_missing_api_key to all other tests in the file: - test_send_email_success - test_send_email_multiple_recipients Instead of relying on fixture-based patching and respx mocks which can fail due to import order and caching issues, directly inject the mock HTTP client into the logger instance. This ensures mocks are always used regardless of test execution order.
This commit is contained in:
parent
bcdfba55b5
commit
0a313efa9a
1 changed files with 27 additions and 48 deletions
|
|
@ -2,9 +2,7 @@ import os
|
|||
import sys
|
||||
import unittest.mock as mock
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
import respx
|
||||
from httpx import Response
|
||||
|
||||
sys.path.insert(0, os.path.abspath("../../.."))
|
||||
|
|
@ -38,32 +36,8 @@ def mock_env_vars():
|
|||
yield
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_httpx_client():
|
||||
with mock.patch(
|
||||
"litellm_enterprise.enterprise_callbacks.send_emails.resend_email.get_async_httpx_client"
|
||||
) as mock_client:
|
||||
|
||||
mock_response = mock.Mock(spec=Response)
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {"id": "test_email_id"}
|
||||
mock_response.raise_for_status.return_value = None
|
||||
|
||||
mock_async_client = mock.AsyncMock()
|
||||
mock_async_client.post.return_value = mock_response
|
||||
|
||||
mock_client.return_value = mock_async_client
|
||||
yield mock_async_client
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@respx.mock
|
||||
async def test_send_email_success(mock_env_vars, mock_httpx_client):
|
||||
# Block all HTTP requests at network level to prevent real API calls
|
||||
respx.post("https://api.resend.com/emails").mock(
|
||||
return_value=httpx.Response(200, json={"id": "test_email_id"})
|
||||
)
|
||||
|
||||
async def test_send_email_success(mock_env_vars):
|
||||
# Initialize the logger
|
||||
logger = ResendEmailLogger()
|
||||
|
||||
|
|
@ -73,14 +47,27 @@ async def test_send_email_success(mock_env_vars, mock_httpx_client):
|
|||
subject = "Test Subject"
|
||||
html_body = "<p>Test email body</p>"
|
||||
|
||||
# Create mock HTTP client and inject it directly into the logger
|
||||
# This ensures the mock is used regardless of any caching/import issues
|
||||
mock_response = mock.Mock(spec=Response)
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {"id": "test_email_id"}
|
||||
mock_response.raise_for_status.return_value = None
|
||||
|
||||
mock_async_client = mock.AsyncMock()
|
||||
mock_async_client.post.return_value = mock_response
|
||||
|
||||
# Directly inject the mock client to bypass any caching
|
||||
logger.async_httpx_client = mock_async_client
|
||||
|
||||
# Send email
|
||||
await logger.send_email(
|
||||
from_email=from_email, to_email=to_email, subject=subject, html_body=html_body
|
||||
)
|
||||
|
||||
# Verify the HTTP client was called correctly
|
||||
mock_httpx_client.post.assert_called_once()
|
||||
call_args = mock_httpx_client.post.call_args
|
||||
mock_async_client.post.assert_called_once()
|
||||
call_args = mock_async_client.post.call_args
|
||||
|
||||
# Verify the URL
|
||||
assert call_args[1]["url"] == "https://api.resend.com/emails"
|
||||
|
|
@ -97,13 +84,7 @@ async def test_send_email_success(mock_env_vars, mock_httpx_client):
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@respx.mock
|
||||
async def test_send_email_missing_api_key():
|
||||
# Block all HTTP requests at network level to prevent real API calls
|
||||
respx.post("https://api.resend.com/emails").mock(
|
||||
return_value=httpx.Response(200, json={"id": "test_email_id"})
|
||||
)
|
||||
|
||||
# Remove the API key from environment before initializing logger
|
||||
original_key = os.environ.pop("RESEND_API_KEY", None)
|
||||
|
||||
|
|
@ -146,13 +127,7 @@ async def test_send_email_missing_api_key():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@respx.mock
|
||||
async def test_send_email_multiple_recipients(mock_env_vars, mock_httpx_client):
|
||||
# Block all HTTP requests at network level to prevent real API calls
|
||||
respx.post("https://api.resend.com/emails").mock(
|
||||
return_value=httpx.Response(200, json={"id": "test_email_id"})
|
||||
)
|
||||
|
||||
async def test_send_email_multiple_recipients(mock_env_vars):
|
||||
# Initialize the logger
|
||||
logger = ResendEmailLogger()
|
||||
|
||||
|
|
@ -162,13 +137,17 @@ async def test_send_email_multiple_recipients(mock_env_vars, mock_httpx_client):
|
|||
subject = "Test Subject"
|
||||
html_body = "<p>Test email body</p>"
|
||||
|
||||
# Mock the response to avoid making real HTTP requests
|
||||
# Create mock HTTP client and inject it directly into the logger
|
||||
mock_response = mock.Mock(spec=Response)
|
||||
mock_response.raise_for_status.return_value = None
|
||||
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {"id": "test_email_id"}
|
||||
mock_httpx_client.post.return_value = mock_response
|
||||
mock_response.raise_for_status.return_value = None
|
||||
|
||||
mock_async_client = mock.AsyncMock()
|
||||
mock_async_client.post.return_value = mock_response
|
||||
|
||||
# Directly inject the mock client to bypass any caching
|
||||
logger.async_httpx_client = mock_async_client
|
||||
|
||||
# Send email
|
||||
await logger.send_email(
|
||||
|
|
@ -176,7 +155,7 @@ async def test_send_email_multiple_recipients(mock_env_vars, mock_httpx_client):
|
|||
)
|
||||
|
||||
# Verify the HTTP client was called with multiple recipients
|
||||
mock_httpx_client.post.assert_called_once()
|
||||
call_args = mock_httpx_client.post.call_args
|
||||
mock_async_client.post.assert_called_once()
|
||||
call_args = mock_async_client.post.call_args
|
||||
request_body = call_args[1]["json"]
|
||||
assert request_body["to"] == to_email
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue