How to Mock a Factory Boy Model Instance in Python
Create a factory boy factory, then patch its Meta.model with a Mock to control instance behavior in tests.
pip install factory-boy
Python code
41 linesimport factory
from dataclasses import dataclass
from unittest.mock import Mock, patch
import builtins
@dataclass
class User:
name: str
age: int
class UserFactory(factory.Factory):
class Meta:
model = User
name = "Alice"
age = 30
def get_user_name(user):
return user.name
def main():
# Create a real factory instance
real_user = UserFactory()
print(f"Real user: {real_user.name}, {real_user.age}")
# Replace the factory's model with a mock to control behavior
mock_model = Mock()
mock_model.return_value = Mock(name="Mocked User", age=42)
with patch.object(UserFactory.Meta, "model", mock_model):
mocked_user = UserFactory()
print(f"Mocked user: {mocked_user.name}, {mocked_user.age}")
print(f"Mock object called: {mock_model.called}")
if __name__ == "__main__":
main()
Output
Real user: Alice, 30
Mocked user: Mocked User, 42
Mock object called: True
How it works
The Meta.model attribute tells factory boy which class to instantiate. Patching it with a Mock replaces the real model class, so every UserFactory() call invokes the mock instead of the dataclass. Setting mock_model.return_value lets you control exactly what attributes and behavior the generated instance exposes. This is useful in tests when the real model is heavy, slow, or has side effects on construction. The patch.object context manager ensures the model is restored after the block exits.
Common mistakes
- Patching the wrong attribute instead of `Meta.model`
- Forgetting to set `mock_model.return_value` so the mock instance has useful attributes
- Calling the factory outside the `patch` context and expecting the mock behavior
- Using `mock_model` directly instead of checking the generated instance's attributes
Variations
- Use `factory.make_factory(User, name='Bob')` to create a lightweight factory without `Meta`
- Patch with a partial mock: `mock_model.side_effect = lambda **kw: User('Default', 0)` to preserve real behavior with overrides
Real-world use cases
- Speed up unit tests by mocking a database-backed model so no DB access happens during factory instantiation.
- Replace a slow third-party SDK client with a mock to test code that consumes factory-created instances.
- Force specific attribute values in a test without needing to set up complex dependent objects.
Sponsored
More from Testing & modern typing
- Capture stdout and stderr with pytest capsys easy
- Characterization Test for Legacy Python Code medium
- Dataclass with Type Hints Fields in Python easy
- Dependency Injection in Python for Testability easy
- Design Data Helpers with Python TypedDict and Literal easy
- Fix and Test a Regression Bug in Python with Unit Tests easy
Keep learning
Related tutorials and quizzes for this topic.