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
Release files for pytest-when 2.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pytest_when-2.3.0.tar.gz | 11.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_when-2.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 20.6 kB
Release files / pytest_when-2.3.0.tar.gz
| Download URL | pytest_when-2.3.0.tar.gz |
|---|---|
| Size | 11.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6edf6bd44508328b74bc0f7859e8128059ba015d2c924c0d3cc9cfd0231767a1
|
|
BLAKE2b-256 checksum How to use checksums |
30a12ae7c2637a5e6e961edb9a7a716e6fc1330dfc6439b50edde0eecce97a08
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.25.9 CPython/3.12.3 Linux/6.11.0-1018-azure
|
Release files / pytest_when-2.3.0-py3-none-any.whl
| Download URL | pytest_when-2.3.0-py3-none-any.whl |
|---|---|
| Size | 9.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fc7e184f288416d7db4010d1cea667ea60f65a742559fdce90f26fd37d071065
|
|
BLAKE2b-256 checksum How to use checksums |
74048e032e875a3affb86c8293b8e41d74cd2ea214473051414525e684e2e2d4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.25.9 CPython/3.12.3 Linux/6.11.0-1018-azure
|