28

I'm having trouble understanding what's happening in some test code. It looks like this:

import pytest
from unittest.mock import MagicMock
from my_module import MyClass

confusing_mock = MagicMock(
    return_value=b"",
    side_effect=[
        ConnectionError(),
        b"another_return_value?",
        b"another_another_return_value?"
    ])

mocked_class = MyClass()
monkeypatch.setattr(mocked_class, "method_to_call_thrice", confusing_mock)

I know that:

  • side_effect is a function to be called whenever the mock is called
  • but if side_effect is an iterable, then "each call to the mock will return the next value from the iterable" (thanks pytest docs)
  • the docs also say that if the function passed to side_effect returns DEFAULT, then the mock will return it's normal value from return_value

But here's what I don't get:

  • What happens when I provide both a list of side effects and a return value?
  • What should I expect to see on each call of MyClass.method_to_call_thrice?
2
  • 1
    The question "unittest.Mock - Combining return_value and side_effect" seems related, but I'm still not quite getting it. Commented May 17, 2019 at 17:42
  • 2
    You could try with a simple return valeu and a simple side effect and see what happens? Commented May 17, 2019 at 17:46

1 Answer 1

39

side_effect is used. A list value can contain mock.DEFAULT, and a function can return mock.DEFAULT, to indicate that the value of the return_value attribute be used.

>>> import unittest.mock
>>> m = unittest.mock.Mock(return_value="foo",
...                        side_effect=[1, 2, unittest.mock.DEFAULT, 4, 5])
>>> m()
1
>>> m()
2
>>> m()
'foo'
>>> m()
4
>>> m()
5
>>> unittest.mock.Mock(return_value="foo",
...                    side_effect=lambda: unittest.mock.DEFAULT)()
'foo'
Sign up to request clarification or add additional context in comments.

1 Comment

To remove an already present side_effect, you can also set it to None (per the docs here)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.