how to get python unit test overwrite variable from imported package

Trying to figure out how to overwrite a variable during unit testing:

#mainscript.py
import json

org_file = 'unitfile.json'

def load_json (file_name):
    with open ('{0}'.format(org_file)) as f:
       json_object =  json.load(f)
    return json_object

new_file = load_json(org_file)

def print_me():
    return (new_file['text'])

def main():
    print_me()

if __name__ == '__main__':
    main()

Unit test:

#test_mainscript.py
import json
import mainscript
import unittest
from  unittest.mock import patch

class Testmainscript(unittest.TestCase):
    # def setUp(self):
        # Not needed when using mock
    @patch('mainscript.org_file','unitfile2.json')
    def test_print_me(self):
        self.assertEqual(mainscript.org_file, 'unitfile2.json') # Correctly overwrites file
        self.assertEqual(mainscript.print_me(),'Bye World') #does not pass, still reading unitfile.json instead of unitfile2.json
if __name__ == '__main__':
    unittest.main()

This test should fail because because I’m overwriting org_file with unitestfile2.json (which contains {'text':'Bye World'}) instead of unittestfile.json (which contains {'text':'Hello World'})

But its currently passing because the variable isn’t being overwritten

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

What you are looking for is called “mocking“, an example for your case:

import json
import mainscript
import unittest
from unittest.mock import patch

class Testmainscript(unittest.TestCase):
    # def setUp(self):
        # Not needed when using mock
 
    @patch('mainscript.org_file', 'unitfile2.json')
    def test_print_me(self):
        self.assertEqual(mainscript.print_me(),'Hello World')

if __name__ == '__main__':
    unittest.main()

Method 2

I found the issue is that I am overwriting the file as expected but when I call the test I am not using the mocked file. Wrapping the function seemed to work:

#mainscript.py
import json


org_file = 'unitfile.json'
def load_json (json_file):
    with open ('{0}'.format(org_file)) as f:
       json_object =  json.load(f)
    return json_object


def print_me(df_file):
    return (df_file['text'])

def main():
    print_me()

if __name__ == '__main__':
    main()

Here I used the wrapped patch as an input

#test_mainscript.py
import json
import mainscript
import unittest
from  unittest.mock import patch

class Testmainscript(unittest.TestCase):
    @patch('mainscript.org_file','unitfile2.json')
    def test_print_me(self):
        self.assertEqual(mainscript.org_file, 'unitfile2.json')
        self.assertEqual(mainscript.print_me(mainscript.load_json(mainscript.org_file)),'Bye World')

if __name__ == '__main__':
    unittest.main()

Test now work:

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x