I don't quite understand why everybody wants to check that foo calls bar.
Foo has some functionality and this functionality needs to be tested. If foo is using bar to do this should not be of my concern.
The desired result is that after foo(msg) is called, is that msg.upper() is sent to stdout.
You can redirect stdout to a string buffer and check if the content of this string buffer matches what you expect.
Example:
import sys
import unittest
from io import TextIOWrapper, BytesIO
class TestScript(unittest.TestCase):
def setUp(self):
self._old_stdout = sys.stdout
sys.stdout = TextIOWrapper(BytesIO(), sys.stdout.encoding)
def _output(self):
self._stdout.seek(0)
return self._stdout.read()
def test_foo(self):
hello_test = HelloTest()
hello_test.foo("blub")
self.assertEqual(self._output(), "BLUB")
def tearDown(self):
sys.stdout = self._old_stdout
self._stdout.close()
You can also do that for stdin (and write to stdin to mock some input) and you can subclass TestIOWrapper if you need anything special to be done, like allowing non-unicode text to be sent to sys.stdout without using sys.stdout.buffer (Python 2 vs. Python 3).
There is an example for that in this SO answer.
When you (still) use Python 2 only, then using StringIO might be better than using the io module.