A global variable can be easily mocked following these answers . Great. However, this does not work when trying to mock a variable in a script that you call with subprocess.call()
in a test with Pytest.
Here is my simplified script in a file called so_script.py
:
import argparse
INCREMENTOR = 4
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('input_nr', type=int, help='An int to increment')
args = parser.parse_args()
with open('test.txt', 'w+') as f:
f.write(str(args.input_nr + INCREMENTOR))
Now, say I want to mock the value of INCREMENTOR
in my tests to be 1
. If I do this:
from subprocess import call
from unittest import mock
def test_increments_with_1():
with mock.patch('so_script.INCREMENTOR', 1):
call(['python', 'so_script.py', '3'])
with open('test.txt', 'r+') as f:
assert f.read() == '4'
The test will fail, because the value of INCREMENTOR
remains 4, even though I tried to patch it to 1. So what gets written to the file is 7 instead of 4.
So my question is: how do I mock the INCREMENTOR
global variable in my so_script.py
file so that, when calling subprocess.call()
on it, it remains mocked?
Because the so_script.py
script and pytest are executed in different processes, one cannot mock objects in so_script.py
while the latter is being called as a different process in tests.
The best solution I found was to put everything from the if __name__ == '__main__:
block in a function and test that function with Pytest, mocking whatever I needed to mock. And, to have 100% test coverage (which was my initial intent with calling the script as a subprocess), I applied this solution .
So I dropped using subprocess.call()
in my tests and wrote an init()
function checking if __name__ == '__main__:
, and then mocked __name__
in the tests to test the function, just as the article advises to do. This got me 100% test coverage and full mocking capabilities.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.