Mocking builtins like print is a little tricky. First, you need to know that they are stored in a special __builtins__ module:
>>> __builtins__.print("hello world")
hello world
So, you need to patch that __builtins__ module. I first tried these:
@patch("__builtins__.print", dec_print)
#and
@patch("__builtin__.print", dec_print)
But these both gave an ImportError.
Next, I tried mock.patch instead of just mock, which lets you specify the object you want to patch (instead of using the string to import the object):
@patch.object(__builtins__, "print", dec_print)
This works, but then since you're calling print inside of dec_print, you get a RuntimeError: maximum recursion depth exceeded error.
So, to fix that you can replace print with sys.stdout.write. Here is the final working code for mocking print:
import sys
from mock import patch
def dec_print(msg):
sys.stdout.write("+++ {}\n".format(msg))
@patch.object(__builtins__, "print", dec_print)
def fun():
print("Hello")
if __name__ == "__main__":
fun()
Output:
$ python x.py
+++ Hello
Edit: in response to the new information you posted (it printed the message twice, once with the mock and once without):
You're seeing it printed twice because you put fun() at the top level of the module, so it runs when @patch imports tstmock, then it runs again normally. You should wrap this call in an if __name__ == '__main__': block (explained here).
...original code...
if __name__ == "__main__":
fun()