Utility which makes mocking more readable and controllable
Project description
pytest-when
Inspired
by mokito-scala, pytest-when
provides a fixture for pytest to simplify the mocking of python objects:
Purpose
More readable than the full Given...When...Then pattern, pytest-when is
meant for developers who want to test for behaviour, without any extra
overhead.
Enable the mock only for a specific argument's values to make code more
readable.
Benefits
In this example, when you specify the first two arguments and any third argument, the attribute will be mocked,
(
when(some_object, "attribute")
.called_with(1, 2, when.markers.any)
.then_return("attribute mocked")
# or
# .then_call(some_callable)
# or
# .then_raise(SomeException())
)
Note that the .called_with method arguments are compared with the real
callable signature.
This gives additional protection against changing the real callable interface.
With when fixture, the following expression:
when(example_module, "some_normal_function").called_with(
"a",
1,
kwarg1="b",
kwarg2=2,
).then_return("Mocked")
is roughly equal to:
mock_only_for_calls = (
call("a", 1, kwarg1="b", kwarg2=2),
"Mocked",
)
def matches(
call: Call,
mocked_calls_registry: tuple[tuple[call, ReturnType], ...],
) -> bool:
...
def create_call(*args, **kwargs) -> Call:
...
def side_effect_callback(*args, **kwargs):
if matches(create_call(*args, **kwargs), mock_only_for_calls):
return mock_only_for_calls[1]
return unittest.mock.DEFAULT
mocker.patch.object(
example_module,
"some_normal_function",
autospec=True,
side_effect=side_effect_callback,
)
where logic of matches and create_call is not trivial
Installation
Install the package into your development environment, from
pypi, using pip, for example:
pip install pytest-when
Implementation
Onced installed, the when fixture will be available just like the rest of
the pytest plugins.
See the following example of how to use it:
# class which we're going to mock in the test
class Klass1:
def some_method(
self,
arg1: str,
arg2: int,
*,
kwarg1: str,
kwarg2: str,
) -> str:
return "some_method not mocked"
def test_should_properly_patch_calls(when):
when(Klass1, "some_method").called_with(
"a",
when.markers.any,
kwarg1="b",
kwarg2=when.markers.any,
).then_return("some method mocked")
assert (
Klass1().some_method(
"a",
1,
kwarg1="b",
kwarg2="c",
)
== "some method mocked"
)
assert (
Klass1().some_method(
"not mocked param",
1,
kwarg1="b",
kwarg2="c",
)
== "some method not mocked"
)
# if you need to patch a function
def test_patch_a_function(when):
when(example_module, "some_normal_function").called_with(
"a",
when.markers.any,
kwarg1="b",
kwarg2=when.markers.any,
).then_return("some_normal_function mocked")
assert (
example_module.some_normal_function(
"a",
1,
kwarg1="b",
kwarg2="c",
)
== "some_normal_function mocked"
)
assert (
example_module.some_normal_function(
"not mocked param",
1,
kwarg1="b",
kwarg2="c",
)
== "some_normal_function not mocked"
)
It is possible to use when with class methods and standalone functions
(in this case cls parameter will become a python module).
You can patch the same object multiple times using different called_with
parameters in a single test.
You can also patch multiple targets (cls, method)
See more examples at: test_integration
Setup for local developement
The project can be extended by cloning the repo and
installing the PDM build tool
So, the development environment requires:
- pdm https://pdm.fming.dev/latest/#installation
- python3.8 or greater
pdm install
To run tests and linters use:
make test
make lint
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 Distribution
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 pytest_when-2.3.0.tar.gz.
File metadata
- Download URL: pytest_when-2.3.0.tar.gz
- Upload date:
- Size: 11.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: pdm/2.25.9 CPython/3.12.3 Linux/6.11.0-1018-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6edf6bd44508328b74bc0f7859e8128059ba015d2c924c0d3cc9cfd0231767a1
|
|
| MD5 |
b447555b4cc97f41bbbef07937fa8c7f
|
|
| BLAKE2b-256 |
30a12ae7c2637a5e6e961edb9a7a716e6fc1330dfc6439b50edde0eecce97a08
|
File details
Details for the file pytest_when-2.3.0-py3-none-any.whl.
File metadata
- Download URL: pytest_when-2.3.0-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: pdm/2.25.9 CPython/3.12.3 Linux/6.11.0-1018-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc7e184f288416d7db4010d1cea667ea60f65a742559fdce90f26fd37d071065
|
|
| MD5 |
6a9a812f8b543badee23b44e3bee9819
|
|
| BLAKE2b-256 |
74048e032e875a3affb86c8293b8e41d74cd2ea214473051414525e684e2e2d4
|