Mocking как встроенные команды print
немного сложнее. Во-первых, вы должны знать, что они хранятся в специальном модуле __builtins__
:
>>> __builtins__.print("hello world")
hello world
Итак, вам нужно пропатчить, что __builtins__
модуль. Я сначала пробовал:
@patch("__builtins__.print", dec_print)
#and
@patch("__builtin__.print", dec_print)
Но они оба дали ImportError
.
Далее я попытался mock.patch
вместо просто mock
, который позволяет указать объект, который нужно пропатчить (вместо того, чтобы использовать строку для импорта объекта):
@patch.object(__builtins__, "print", dec_print)
Это работает, но так как вы 'вызвав print
внутри dec_print
, вы получаете ошибку RuntimeError: maximum recursion depth exceeded
.
Итак, чтобы исправить это, вы можете заменить print
на sys.stdout.write
. Вот окончательный рабочий код для насмешливого 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()
Выход:
$ python x.py
+++ Hello
Edit: в ответ на новую информацию, которую вы публикуемой (напечатанное сообщение дважды, один раз с издеваться и один раз без):
Вы видите его дважды напечатанным, потому что вы положили fun()
на верхний уровень модуля, поэтому он работает, когда @patch
импортирует tstmock
, тогда он снова запускается нормально. Вы должны обернуть этот вызов в блок if __name__ == '__main__':
(объяснено here).
...original code...
if __name__ == "__main__":
fun()
Что вы пытаетесь достичь? Что вы пытаетесь насмехаться? Вы можете немного пояснить? –