简体   繁体   中英

Pytest mock global variable in subprocess.call()

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM