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")
)
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
File details
Details for the file pytest_when-2.0.0.tar.gz
.
File metadata
- Download URL: pytest_when-2.0.0.tar.gz
- Upload date:
- Size: 9.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: pdm/2.15.3 CPython/3.10.12 Linux/6.5.0-1021-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | e6fc7be98b3f63c587cd9044da310c3ba63109ac48c2debacf2426cbe64e0c09 |
|
MD5 | 73357411915e09908a1137ee78fc8853 |
|
BLAKE2b-256 | 9bbbe62aa8a23a68bcf67886b384c719bb066afb0e0e43fcea2a84173b242c9d |
File details
Details for the file pytest_when-2.0.0-py3-none-any.whl
.
File metadata
- Download URL: pytest_when-2.0.0-py3-none-any.whl
- Upload date:
- Size: 7.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: pdm/2.15.3 CPython/3.10.12 Linux/6.5.0-1021-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 15a87e2d3e92673c24a49e5e607c957569260cbb64a00f9384352f81a914492b |
|
MD5 | f1ce1e7a0bacb3a90537b07e5e97688f |
|
BLAKE2b-256 | db4b1721bfc49bf840fbb97262d3fdda763da79c56e7bb0b7926260c98325d96 |