In unittest
I can assert to side_effect iterable with values - each of them one-by-one will be returned when patched method called, moreover I found that in unittest
my patched method can return different results according to input arguments. Can I make something like that in pytest? Documentation does not mention this.

- 1
- 1

- 13,032
- 8
- 47
- 81
2 Answers
You can use Mock's side_effect parameter to set what is to be returned for each call.
side_effect: A function to be called whenever the Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT, the return value of this function is used as the return value. Alternatively side_effect can be an exception class or instance. In this case the exception will be raised when the mock is called. If side_effect is an iterable then each call to the mock will return the next value from the iterable. A side_effect can be cleared by setting it to None.
For instance:
return_data = [3, 5]
test_mock = Mock(side_effect=return_data)
monkeypatch.setattr(your_module, "some_func", test_mock)
This way first time your call calls "some_func" it will return 3 and when you call it a second time it will return 5
Then you can if it was called twice
assert test_mock.call_count == len(return_data)
return data should be Iterable (list, set, tuple) and can contain anything you would like (int, string, object, tuples, lists, ...)

- 83,883
- 25
- 248
- 179
You could certainly monkeypatch something with a class with a __call__
attribute which does whatever you want - however, nothing keeps you from using unittest.mock
with pytest - there's even the pytest-mock
plugin to make this easier.

- 11,126
- 4
- 40
- 54