Implementation:Langchain ai Langchain ChatModelUnitTests Subclass
Overview
Concrete standard test suite class for validating LangChain chat model implementations in unit test mode (no network access), provided by ChatModelUnitTests in the langchain-tests package.
Description
ChatModelUnitTests is a base test class in langchain_tests.unit_tests that provides 30+ pre-built test methods for validating chat model implementations without making any network calls. Integration authors subclass it, provide the model class and initialization parameters, and immediately inherit a comprehensive test battery.
Required overrides:
chat_model_class: Property returning the chat model class under test.chat_model_params: Property returning a dict of initialization parameters.
Optional overrides:
init_from_env_params: Tuple of (env_vars, constructor_args, expected_values) for testing environment variable initialization.has_tool_calling: Whether the model supports tool calling (auto-detected by default).has_tool_choice: Whether the model supportstool_choiceparameter.has_structured_output: Whether the model supports structured output.supports_json_mode: Whether the model supports JSON mode output.supports_image_inputs: Whether the model supports image message content.supports_video_inputs: Whether the model supports video message content.
Included test methods (partial list):
test_init-- Model instantiation with provided paramstest_init_from_env-- Initialization from environment variablestest_serdes-- Serialization and deserialization round-triptest_standard_params-- Standard LLM parameters (temperature, max_tokens, etc.)test_bind_tool_pydantic-- Tool binding with Pydantic modelstest_with_structured_output-- Structured output interfacetest_tool_message_content_is_str-- Tool message serializationtest_chat_model_is_accessible_from_init-- Module import validationtest_configurable_fields-- Dynamic field configurationtest_configurable_alternatives-- Alternative model configurationstest_declarative_methods-- Declarative API methods
Usage
Use this class as the base for unit tests in every LangChain partner integration package. Place the test file at tests/unit_tests/test_chat_models.py.
Code Reference
Source Location: libs/standard-tests/langchain_tests/unit_tests/chat_models.py, Lines 276-740+
Class Signature:
class ChatModelUnitTests(ChatModelTests):
"""Base class for chat model unit tests.
Test subclasses must implement the `chat_model_class` and
`chat_model_params` properties to specify what model to test and its
initialization parameters.
"""
@property
@abstractmethod
def chat_model_class(self) -> type[BaseChatModel]:
...
@property
def chat_model_params(self) -> dict[str, Any]:
return {}
Import:
from langchain_tests.unit_tests import ChatModelUnitTests
I/O Contract
| Input | Type | Description |
|---|---|---|
chat_model_class |
type[BaseChatModel] |
The chat model class to test |
chat_model_params |
dict[str, Any] |
Initialization parameters (model name, API key, etc.) |
init_from_env_params |
tuple[dict, dict, dict] |
Optional: (env_vars, constructor_args, expected_values) |
| Output | Type | Description |
|---|---|---|
| Test results | pytest outcomes | Pass/fail/skip for each of the 30+ test methods |
| Assertions | N/A | Validates model interface compliance without network calls |
Usage Examples
Minimal subclass (DeepSeek example):
from langchain_tests.unit_tests import ChatModelUnitTests
from langchain_deepseek.chat_models import ChatDeepSeek
class TestChatDeepSeekUnit(ChatModelUnitTests):
@property
def chat_model_class(self) -> type[ChatDeepSeek]:
return ChatDeepSeek
@property
def chat_model_params(self) -> dict:
return {
"model": "deepseek-chat",
"api_key": "api_key",
}
@property
def init_from_env_params(self) -> tuple[dict, dict, dict]:
return (
{
"DEEPSEEK_API_KEY": "api_key",
"DEEPSEEK_API_BASE": "api_base",
},
{
"model": "deepseek-chat",
},
{
"api_key": "api_key",
"api_base": "api_base",
},
)
Running unit tests:
cd libs/partners/deepseek
# Run all unit tests with network disabled
uv run --group test pytest --disable-socket --allow-unix-socket tests/unit_tests/
# Run a specific test method
uv run --group test pytest --disable-socket tests/unit_tests/test_chat_models.py::TestChatDeepSeekUnit::test_init
Custom tests alongside standard tests:
class TestChatDeepSeekCustomUnit:
"""Custom tests specific to DeepSeek that go beyond standard tests."""
def test_create_chat_result_with_reasoning_content(self) -> None:
chat_model = ChatDeepSeek(model="deepseek-chat", api_key=SecretStr("key"))
# ... test DeepSeek-specific reasoning_content extraction