Skip to content

Commit

Permalink
Add comparison between when and no-when
Browse files Browse the repository at this point in the history
Compare how the solution might look like if there is no
when fixture (pseudocode)
  • Loading branch information
zhukovgreen committed Jan 29, 2024
1 parent 77635cf commit f885267
Showing 1 changed file with 69 additions and 22 deletions.
91 changes: 69 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,58 @@ Inspired by <https://github.com/mockito/mockito-scala>
real callable signature and gives additional protection against
changing the real callable interface.

With `when` fixture, the following expression:

```python
when(example_module, "some_normal_function").called_with(
"a",
1,
kwarg1="b",
kwarg2=2,
).then_return("Mocked")

```

is roughly equal to:

```python

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

```bash
pip install pytest-when
```


## Usage

After installing the package a new fixture `when` will be available.
Expand All @@ -37,12 +82,12 @@ See the following example 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,
self,
arg1: str,
arg2: int,
*,
kwarg1: str,
kwarg2: str,
) -> str:
return "Not mocked"

Expand All @@ -56,24 +101,25 @@ def test_should_properly_patch_calls(when):
).then_return("Mocked")

assert (
Klass1().some_method(
"a",
1,
kwarg1="b",
kwarg2="c",
)
== "Mocked"
Klass1().some_method(
"a",
1,
kwarg1="b",
kwarg2="c",
)
== "Mocked"
)
assert (
Klass1().some_method(
"not mocked param",
1,
kwarg1="b",
kwarg2="c",
)
== "Not mocked"
Klass1().some_method(
"not mocked param",
1,
kwarg1="b",
kwarg2="c",
)
== "Not mocked"
)


# if you need to patch a function
def test_patch_a_function(when):
when(example_module, "some_normal_function").called_with(
Expand Down Expand Up @@ -114,10 +160,10 @@ You can also patch multiple targets (cls, method)
See more examples at:
[test_integration](tests/test_integration.py)


## Setup for local developement

Requirements:

1. pdm <https://pdm.fming.dev/latest/#installation>
2. python3.8 (minimum supported by a tool)

Expand All @@ -126,6 +172,7 @@ pdm install
```

To run tests and linters use:

```bash
make test
make lint
Expand Down

0 comments on commit f885267

Please sign in to comment.