So I am practicing some unit test and I am trying to check for an output that is within a For Loop. Here is my run code
def main():
for i in range(100):
print("Argh!")
Pretty basic, now here is my test code.
import unittest
from unittest import mock # possibly "from unittest import mock" depending on version.
from RunFile import main
class TestMain(unittest.TestCase):
def test_main(self):
with mock.patch.object(main(), 'print') as mock_print:
main()
expected_calls = [mock.call('Argh!') for _ in range(100)]
mock_print.assert_has_calls(expected_calls)
if __name__ == '__main__':
unittest.main()
Here is the error message I get back. I'm not to sure how to resolve this. UPDATED: Here is the full trace back
======================================================================
ERROR: test_main (__main__.TestMain)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:/Users/jsalce/Documents/Testsuites/IfStatements/Testsuite.py", line 9, in test_main
with mock.patch.object(RunFile, 'print') as mock_print:
File "C:\Python33\lib\unittest\mock.py", line 1148, in __enter__
original, local = self.get_original()
File "C:\Python33\lib\unittest\mock.py", line 1122, in get_original
"%s does not have the attribute %r" % (target, name)
AttributeError: <module 'RunFile' from 'C:\\Users\\jsalce\\Documents\\Testsuites\\IfStatements\\RunFile.py'> does not have the attribute 'print'
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
Thank you all in advance!
Generally speaking, for mock.patch.object, you want to patch something that you have an easy handle on -- e.g. a module or a class. Usually, you need to patch something that is one level above what you want to replace. For example if you want to patch the foo function in module bar, then you need mock.patch.object(bar, 'foo').
In your case, technically, print is a builtin, but you can patch it on the module where you're using it. This will add a RunFile.print "method" (which is actually a mock) that you can test assertions against. Apparently, since print doesn't actually exist on the module, we need to add create=True to tell mock to create RunFile.print since it doesn't already exist. With that in mind, I'd re-write the unittest as:
import RunFile
class TestMain(unittest.TestCase):
def test_main(self):
with mock.patch.object(RunFile, 'print', create=True) as mock_print:
RunFile.main()
expected_calls = [mock.call('Argh!') for _ in range(100)]
mock_print.assert_has_calls(expected_calls)
if __name__ == '__main__':
unittest.main()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With