flexmock
flexmock is a Python testing library that simplifies the creation of mocks, stubs, and fakes. It's designed to be flexible and expressive for isolating code under test. The current version is 0.13.0, and it maintains an active release cadence, frequently updating for Python version compatibility and dependency bumps.
Common errors
-
AttributeError: 'Mock' object has no attribute 'some_method'
cause You are trying to call a method or access an attribute on a mocked object that was not explicitly defined or allowed by the mock. This means the mock did not correctly intercept the call or the method wasn't mocked.fixEnsure the `should_receive()` chain correctly targets the method you intend to mock, including its name and any arguments if necessary. For attributes, use `and_return()` directly or `set()`. -
AssertionError: expected 'method_name' to be called once but was called 0 times
cause This error occurs during mock verification (`should_have_received`) when the mocked method was never actually called by the code under test, or was called on a different object than the one mocked.fixDouble-check that your code under test indeed calls the method you mocked, and that it operates on the exact object you set up the mock for. Pay attention to class vs. instance mocks. -
My tests are flaky or failing intermittently when run in a suite, but pass individually.
cause This is a classic sign of mocks not being properly reset between test runs, leading to state leakage and interference between tests.fixEnsure `flexmock_teardown()` is called after every test. If using `unittest`, call it in `tearDown()`. If using `pytest`, use the `flexmock` fixture in your tests (`def test_my_feature(flexmock): ...`) or create an `autouse` fixture to ensure `flexmock_teardown()` runs. -
TypeError: 'Mock' object is not subscriptable
cause You are attempting to access a mocked object using dictionary-like subscription (e.g., `mock_obj['key']`) without explicitly mocking the `__getitem__` method.fixTo mock dictionary-like access, explicitly mock the `__getitem__` method: `flexmock(obj).should_receive('__getitem__').with_args('key').and_return('value')`.
Warnings
- breaking flexmock v0.13.0 dropped support for Python 3.8. Earlier versions dropped 3.6 and 3.7. Ensure your Python environment meets the `flexmock` version requirements.
- gotcha Mocks created with `flexmock` do not automatically clean up in all testing contexts. Failure to explicitly call `flexmock_teardown()` or use appropriate test runner integration can lead to mocks leaking between tests, causing flaky or incorrect test results.
- gotcha The `flexmock.new_instances()` method is specifically for mocking *class instantiation* (i.e., when `__init__` is called), not for mocking methods on an already existing class or a new instance after creation. Misunderstanding this can lead to mocks not being applied as expected.
- deprecated As of v0.12.0, flexmock's pytest integration switched to use native pytest hooks and a direct `flexmock` fixture. While older `pytest-flexmock` plugins might still function, the recommended approach is to rely on the library's built-in support.
Install
-
pip install flexmock
Imports
- flexmock
from flexmock import flexmock
- flexmock_teardown
from flexmock.mock import flexmock_teardown
from flexmock import flexmock_teardown
Quickstart
import datetime
from flexmock import flexmock, flexmock_teardown
def get_today_str():
return datetime.date.today().isoformat()
# --- Example Test (usually in a test file) ---
# The flexmock_teardown() is crucial for cleaning up mocks.
# In pytest, use the flexmock fixture. In unittest, call it in tearDown.
# For a standalone script, call it manually.
try:
# Mock the 'today' method of the datetime.date class
flexmock(datetime.date).should_receive('today').and_return(datetime.date(2023, 10, 26))
# Call the function under test
result = get_today_str()
# Assert the result
assert result == '2023-10-26'
print(f"Test passed: Today's date is mocked to {result}")
finally:
# Ensure mocks are cleaned up
flexmock_teardown()