An extension of fabricatio, which provides mocks and other test utils.
Project description
fabricatio-mock
Test utilities and mock implementations for fabricatio. Provides configurable dummy LLM responses so you can test agent workflows without real API calls.
Installation
pip install fabricatio[mock]
# or
uv pip install fabricatio[mock]
For a full installation that includes this package and all other components:
pip install fabricatio[full]
# or
uv pip install fabricatio[full]
Quick Start
The primary API uses install_router_usage (a context manager) with return_router_usage
to inject dummy responses into the Rust-side router singleton:
import pytest
from fabricatio_mock.utils import install_router_usage
from fabricatio_mock.models.mock_router import return_router_usage
@pytest.mark.asyncio
async def test_my_role():
# Responses are returned in FIFO order across calls.
# The default value is appended automatically for safety.
with install_router_usage(*return_router_usage("Hello", "World")):
result = await some_llm_call(question="greet")
assert result == "Hello"
result = await some_llm_call(question="farewell")
assert result == "World"
Important: unique question strings
The router uses a persistent response cache keyed by request hash. Every test case MUST use a unique question string to avoid stale cache hits from previous tests:
# GOOD - unique questions per test case
@pytest.mark.parametrize("expected", ["Hi", "Hello"])
async def test_greeting(expected):
with install_router_usage(*return_router_usage(expected)):
result = await role.aask(
send_to="openai/gpt-3.5-turbo",
question=f"q_greeting_{expected}", # unique per parametrize case
)
assert result == expected
# BAD - "Hi" and "Hello" collide across parametrize cases
@pytest.mark.parametrize("expected", ["Hi", "Hello"])
async def test_greeting_bad(expected):
with install_router_usage(*return_router_usage(expected)):
result = await role.aask(
send_to="openai/gpt-3.5-turbo",
question="test", # same hash -> stale cache hit
)
assert result == expected
Response Builders
All return_*_router_usage functions return a list[str] ready to unpack into install_router_usage.
| Function | Description |
|---|---|
return_router_usage(*values, default=) |
Plain string responses |
return_json_router_usage(*jsons, default=) |
Wraps each in a JSON code block |
return_code_router_usage(*codes, lang=, default=) |
Wraps each in a fenced code block |
return_python_router_usage(*codes, default=) |
Shorthand for lang="python" |
return_json_obj_router_usage(*objs, default=) |
Serializes objects with orjson then wraps in JSON block |
return_model_json_router_usage(*models, default=) |
Serializes Pydantic models then wraps in JSON block |
return_generic_router_usage(*strings, lang=, default=) |
Wraps each in a generic delimiter block |
return_mixed_router_usage(*values, default=) |
Accepts Value dataclass for mixed-type responses |
Value dataclass
For tests that need different response formats within a single sequence:
from fabricatio_mock.models.mock_router import Value, return_mixed_router_usage
from fabricatio_mock.utils import install_router_usage
with install_router_usage(*return_mixed_router_usage(
Value(source='{"key": "val"}', type="json"),
Value(source='print("hi")', type="python"),
Value(source="raw text", type="raw", convertor=lambda s: s.upper()),
)):
...
Type options: "model", "json", "python", "generic", "raw".
Test Roles
Pre-configured roles for testing LLM and Propose capabilities:
from fabricatio_mock.models.mock_role import LLMTestRole, ProposeTestRole
role = LLMTestRole(name="tester")
# llm_send_to="openai/gpt-3.5-turbo"
# llm_api_endpoint="https://api.openai.com/v1"
# llm_api_key=SecretStr("sk-123456789")
Helper Utilities
| Function | Description |
|---|---|
install_router_usage(*responses, group=) |
Context manager: configures the router singleton with dummy responses |
setup_dummy_responses(*responses, group=) |
Same as above but not a context manager (permanent until next call) |
code_block(content, lang) |
Wraps content in a fenced code block |
generic_block(content, lang) |
Wraps content in --- Start/End of ... --- delimiters |
make_roles(names, role_cls) |
Creates a list of Role instances from names |
make_n_roles(n, role_cls) |
Creates n Role instances with auto-generated names |
setup_dummy_embeddings(*embeddings, group=, model_id=) |
Configures router with dummy embedding vectors |
install_dummy_embeddings(*embeddings, group=, model_id=) |
Context manager version of the above |
setup_dummy_reranks(*rankings, group=, model_id=) |
Configures router with dummy reranker ranking tuples |
install_dummy_reranks(*rankings, group=, model_id=) |
Context manager version of the above |
How It Works
fabricatio delegates LLM calls to a Rust-side singleton router (rust.ROUTER).
install_router_usage mutates this singleton in-place by:
- Registering a
DummyProvider - Deploying a
DummyModelwith the given responses to the"openai/gpt-3.5-turbo"route
Responses are popped from the model's queue in LIFO order internally; the builder functions reverse them before storing so callers get FIFO semantics.
Because the router is a shared Arc, all code paths that call through router_usage.ask()
see the injected responses automatically.
Legacy API
The older install_router + return_string API patches rust.ROUTER at the Python level.
This no longer intercepts calls made through UseLLM (which delegates to rust.router_usage.ask()).
These functions are kept for backward compatibility but should not be used for new tests:
install_router(router)— Python-levelunittest.mock.patchonrust.ROUTERreturn_string(*values)— returns a mockRouterobjectreturn_json_string,return_python_string,return_code_string,return_generic_string, etc.
License
MIT - see LICENSE
Embedding & Rerank Mocking
In addition to completion mocking, fabricatio-mock supports embedding and reranker mocking.
Constants
| Constant | Default Value | Description |
|---|---|---|
DUMMY_EMBEDDING_GROUP |
"embedding" |
Default router group for mock embedding models |
DUMMY_RERANKER_GROUP |
"reranker" |
Default router group for mock reranker models |
Embedding Mock Example
from fabricatio_mock.utils import install_dummy_embeddings
from fabricatio_mock.models.mock_router import pad_embeddings
# Create padded embedding responses (handles retries/batches)
embeddings = pad_embeddings([1.0, 0.0, 0.0], [0.0, 1.0, 0.0])
with install_dummy_embeddings(*embeddings):
result = await router.embedding("embedding/dummy/test-embedding-model", ["hello world"])
assert result[0] == [1.0, 0.0, 0.0]
Rerank Mock Example
from fabricatio_mock.utils import install_dummy_reranks
from fabricatio_mock.models.mock_router import pad_rankings
# Create padded ranking responses
rankings = pad_rankings((0, 0.95), (1, 0.5))
with install_dummy_reranks(*rankings):
result = await router.rerank("reranker/dummy/test-reranker-model", "query", ["doc1", "doc2"])
assert result == [(0, 0.95)]
Pad Functions
| Function | Description |
|---|---|
pad_embeddings(*embeddings, default=, padding=) |
Pads embedding vectors with copies of the default for DummyModel safety |
pad_rankings(*rankings, default=, padding=) |
Pads ranking tuples with copies of the default for DummyModel safety |
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fabricatio_mock-0.3.0-py3-none-any.whl.
File metadata
- Download URL: fabricatio_mock-0.3.0-py3-none-any.whl
- Upload date:
- Size: 14.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
baf4d85c12dc921ac2ceb87bac8ea3502f935073c6dbf899b08f6b2f60704f3a
|
|
| MD5 |
9082ad7bb0d260a292a7660ddb25a295
|
|
| BLAKE2b-256 |
d17b4dfadeafcee9035f7fbe1114e2eff1c816939311fcc617cc8df01a3e3696
|