0

I am learning to mock in python but I am not even able to get the basic mocking working. Please give your suggestion to fix the below code snippet..

from mock import patch

def dec_print(msg)
    print("+++ " + msg)

@patch("print", dec_print)
def fun():
    print("Hello");


fun()

Thanks Jude

Michele d'Amico
  • 22,111
  • 8
  • 69
  • 76
jude m
  • 45
  • 1
  • 7

2 Answers2

0

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()
Community
  • 1
  • 1
Steven Kryskalla
  • 14,179
  • 2
  • 40
  • 42
0

Thanks a lot for the input, I managed to get to working by changing the code as below.

from mock import patch

def log(msg):
    print(msg)

def dec_print(msg):
    print("+++ " + msg)

@patch("tstmock.log", dec_print)
def fun():
    log("Hello")

fun()

However, even after I patched the function log, it is getting called and generating below output

+++ Hello
Hello
jude m
  • 45
  • 1
  • 7
  • No problem! 1. You should edit your original question with this information. The answers section here is just for answers. 2. 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: http://stackoverflow.com/questions/419163/what-does-if-name-main-do I updated my answer with this information as well. – Steven Kryskalla Mar 02 '15 at 06:09