Last active
February 17, 2019 09:58
-
-
Save HorlogeSkynet/6f41e58fa30fe3da90f9804ab5983d5e to your computer and use it in GitHub Desktop.
How to reset a mocked object during test in Python 3 ?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import unittest | |
from subprocess import check_output | |
from unittest.mock import patch | |
class YourClass(object): | |
def __init__(self): | |
self.values = [] | |
self.values.append( | |
check_output(['echo', 'foo'], universal_newlines=True).rstrip() | |
) | |
self.values.append( | |
check_output(['echo', 'bar'], universal_newlines=True).rstrip() | |
) | |
self.values.append( | |
check_output(['echo', 'dead'], universal_newlines=True).rstrip() | |
) | |
self.values.append( | |
check_output(['echo', 'beef'], universal_newlines=True).rstrip() | |
) | |
class FakeCheckOutputMock(object): | |
@patch( # Here we mock the original `check_output` object | |
'subprocess.check_output', | |
return_value='Mocked !' | |
) | |
def __init__(self, check_output_mock): | |
# In this list, you specify what object will act in your mock | |
# We use a list for its ordering aspect. | |
self.answers = [ | |
check_output, # 1st `check_output` call will behave "regularly" | |
check_output_mock, # 2nd call will be mocked | |
check_output, # ... and so one | |
check_output_mock, | |
] | |
def method(self, *args, **kwargs): | |
# Here we : | |
# * Pop the first element of the list above | |
# * Use it as a function... | |
# * Called with the parameters passed to the mock | |
# (like `universal_newlines` for instance) | |
return self.answers.pop(0)(*args, **kwargs) | |
class MyTest(unittest.TestCase): | |
@patch( | |
# Let's patch the `check_output` object of this module | |
'__main__.check_output', | |
# The class is instantiated only one time | |
# and the `side_effect` will be one of its methods. | |
side_effect=FakeCheckOutputMock().method | |
) | |
def test_my(self, check_output_mock): | |
self.assertListEqual(YourClass().values, [ | |
'foo', | |
'Mocked !', | |
'dead', | |
'Mocked !' | |
]) | |
if __name__ == '__main__': | |
unittest.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment