Registry / testing / alchemy-mock

alchemy-mock

JSON →
library0.4.3pypypi✓ verified 85d ago

Alchemy-Mock (version 0.4.3) provides helpers for mocking SQLAlchemy sessions in unit tests, allowing for assertions against SQLAlchemy expressions. The project appears to be abandoned since its last release in 2019, with a community-maintained fork, `mock-alchemy`, now serving as an actively developed alternative.

pip install alchemy-mock
INSTALL
IMPORT
SIG · ALCHEMY-MOCK
A
alchemy-mock
testingpythonv0.4.3
Install
3.5s avg
Import
1015ms
Disk
45MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v0.4.3 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.920 runs
installs and imports cleanly · install 0.0s · import 1.067s · 42.7MB
glibc
py 3.103.920 runs
installs and imports cleanly · install 3.5s · import 0.963s · 41MB
45MB installed
● package 45MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

AlchemyMagicMock
from alchemy_mock.mocking import AlchemyMagicMock
UnifiedAlchemyMagicMock
from alchemy_mock.mocking import UnifiedAlchemyMagicMock
ExpressionMatcher
from alchemy_mock.comparison import ExpressionMatcher

This quickstart demonstrates how to use `UnifiedAlchemyMagicMock` to mock a SQLAlchemy session. It includes an example of stubbing query results and asserting on method calls. It also highlights a common behavior where the mock session doesn't perform actual filtering on objects added to it, requiring different assertion strategies.

import unittest from unittest import mock from sqlalchemy import create_engine, Column, Integer, String from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base from alchemy_mock.mocking import UnifiedAlchemyMagicMock # Define a simple SQLAlchemy model for demonstration Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String) email = Column(String) def __repr__(self): return f"<User(id={self.id}, name='{self.name}', email='{self.email}')>" # Example usage of UnifiedAlchemyMagicMock def get_user_by_name(session, name): return session.query(User).filter(User.name == name).first() def add_user(session, name, email): user = User(name=name, email=email) session.add(user) session.commit() return user class TestUserService(unittest.TestCase): def test_get_user_by_name(self): mock_session = UnifiedAlchemyMagicMock( data=[([mock.call.query(User), mock.call.filter(User.name == 'Alice')], [User(id=1, name='Alice', email='alice@example.com')])] ) user = get_user_by_name(mock_session, 'Alice') self.assertIsNotNone(user) self.assertEqual(user.name, 'Alice') mock_session.filter.assert_called_once_with(User.name == 'Alice') def test_add_user(self): mock_session = UnifiedAlchemyMagicMock() new_user = add_user(mock_session, 'Bob', 'bob@example.com') # In alchemy-mock, the mock session doesn't apply filters to added models, so querying them directly might not work as expected. # However, you can assert that the add and commit calls happened. mock_session.add.assert_called_once() mock_session.commit.assert_called_once() # To retrieve added data, you typically would configure 'data' if querying after adding. # Or, assert on the object passed to add. self.assertEqual(new_user.name, 'Bob') self.assertEqual(new_user.email, 'bob@example.com') # To run the tests (example): if __name__ == '__main__': unittest.main()
Debug
Known issues
breakingThe `alchemy-mock` project appears to be abandoned, with no new releases since November 2019. For ongoing development and better Python version compatibility, consider migrating to the actively maintained fork `mock-alchemy` (PyPI: `mock-alchemy`, GitHub: `rajivsarvepalli/mock-alchemy`).
fix
For new projects or if encountering issues with newer Python/SQLAlchemy versions, install `mock-alchemy` instead: `pip install mock-alchemy`. Update imports from `alchemy_mock` to `mock_alchemy`.
affects: <=0.4.3
gotchaWhen using `UnifiedAlchemyMagicMock`, `session.query(Model).filter(...)` will return all data provided in `UnifiedAlchemyMagicMock(data=...)` if you've also added models to the session, as the mock does not perform actual filtering on the added models.
fix
Design your tests to assert on the `filter` calls themselves (e.g., `mock_session.filter.assert_called_once_with(...)`) rather than relying on the return value of subsequent filters on added data. For specific query results based on filters, pre-configure the `data` parameter of `UnifiedAlchemyMagicMock` with expected inputs and outputs.
affects: All versions
gotchaMocking `scalar()` has specific behaviors: querying on columns expects an indexable sequence from the mocked data, while querying on a table expects a non-indexable object. Misconfiguration can lead to unexpected `TypeError` or incorrect return values.
fix
Ensure your mocked data for `scalar()` calls matches the expected type: a sequence (e.g., `[value]`) for column queries and a single object for table queries (e.g., `[Model()]`).
affects: All versions
deprecatedThe original `alchemy-mock` repository has an open issue (#35) regarding 'Importing ABC directly from collections will be removed in Python 3.10', indicating potential compatibility issues with Python 3.10+.
fix
This issue is addressed in the `mock-alchemy` fork. If you need to use `alchemy-mock` with Python 3.10+, you may encounter this. Consider upgrading to `mock-alchemy`.
affects: 0.4.3 (Python 3.10+)
Errors
Common errors & fixes
AttributeError: 'MagicMock' object has no attribute 'filter' (or '.all', '.first', etc.)
This typically occurs when a mock in a chained call is not configured with `return_value`, so an intermediate call returns a generic `MagicMock` instead of a mock configured to respond to the next method in the chain.
fix
Ensure all parts of your SQLAlchemy query chain are correctly mocked with `return_value`. For example, instead of `session.query.filter.return_value = ...`, use `session.query.return_value.filter.return_value = ...` or use `UnifiedAlchemyMagicMock` which handles common chains.
TypeError: 'BinaryExpression' object is not callable
Attempting to pass a SQLAlchemy binary expression (e.g., `User.id == 1`) directly to `mock.call(...)` or `assert_called_with` when the underlying mock expects a comparable object, but the mock library doesn't know how to compare the SQLAlchemy expression type.
fix
Wrap SQLAlchemy expressions with `ExpressionMatcher` from `alchemy_mock.comparison` when asserting calls that involve such expressions. For example, `mock_session.filter.assert_called_once_with(ExpressionMatcher(User.name == 'Alice'))`.
TypeError: object of type 'MagicMock' has no len() (or 'is not subscriptable') when mocking scalar()
This indicates an incorrect return type for a `scalar()` mock. When querying a column with `scalar()`, the mock expects an indexable sequence (e.g., `[value]`). When querying a table and getting a single object, it expects a non-indexable single object.
fix
Adjust the mocked data for `scalar()`: if it's a column query, provide data as `[value]`. If it's a table query returning a single object, provide data as `[obj]`, ensuring the mock returns `obj` directly for `scalar()`.
Upgrade
Version history
0.4.3latest on PyPI · released Nov 5, 2019
Audit
Dependencies
SQLAlchemyrequiredThis library mocks SQLAlchemy sessions; SQLAlchemy is a core dependency for its functionality.
mockrequiredRelies on Python's `mock` (or `unittest.mock` for Python 3.3+) for core mocking capabilities.
Agent activity
48 hits · last 30 days
node
40
OpenAI (training)
1
Resources
alchemy-mock — pip install alchemy-mock · libregistry