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