diff --git a/litellm/main.py b/litellm/main.py index 7775922ea44..7db4e5648e3 100644 --- a/litellm/main.py +++ b/litellm/main.py @@ -6062,7 +6062,7 @@ def completion( custom_llm_provider=custom_llm_provider, model_id=optional_params.get("model_id"), ) - if mock_response or mock_tool_calls or mock_timeout: + if mock_response is not None or mock_tool_calls or mock_timeout: kwargs.pop("mock_timeout", None) # remove for any fallbacks triggered return mock_completion( model, diff --git a/tests/unit/test_empty_mock_response.py b/tests/unit/test_empty_mock_response.py new file mode 100644 index 00000000000..dbae14f344d --- /dev/null +++ b/tests/unit/test_empty_mock_response.py @@ -0,0 +1,46 @@ +from unittest.mock import patch + +import pytest + +import litellm + + +@pytest.mark.parametrize("mock_response", ["", "Hello"]) +@pytest.mark.parametrize("stream", [False, True]) +def test_completion_mock_response(mock_response: str, stream: bool) -> None: + with patch("httpx.Client.send", side_effect=AssertionError("Unexpected HTTP request")): + response = litellm.completion( + model="openai/gpt-4o-mini", + messages=[{"role": "user", "content": "hi"}], + mock_response=mock_response, + stream=stream, + ) + if stream: + content = "".join(chunk.choices[0].delta.content or "" for chunk in response) + else: + content = response.choices[0].message.content + assert content == mock_response + + +@pytest.mark.asyncio +@pytest.mark.parametrize("mock_response", ["", "Hello"]) +@pytest.mark.parametrize("stream", [False, True]) +async def test_acompletion_mock_response(mock_response: str, stream: bool) -> None: + with ( + patch( + "httpx.AsyncClient.send", + side_effect=AssertionError("Unexpected HTTP request"), + ), + patch("httpx.Client.send", side_effect=AssertionError("Unexpected HTTP request")), + ): + response = await litellm.acompletion( + model="openai/gpt-4o-mini", + messages=[{"role": "user", "content": "hi"}], + mock_response=mock_response, + stream=stream, + ) + if stream: + content = "".join([chunk.choices[0].delta.content or "" async for chunk in response]) + else: + content = response.choices[0].message.content + assert content == mock_response