我与python mock的斗争

时间:2015-03-01 18:11:33

标签: unit-testing python-2.7 mocking

我正在学习在python中进行模拟,但我甚至无法进行基本的模拟工作。请提供您的建议以修复以下代码段..

from mock import patch

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

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


fun()

由于 犹大书

2 个答案:

答案 0 :(得分:0)

模仿像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

编辑:响应您发布的新信息(打印消息两次,一次使用模拟,一次不使用):

您看到它打印了两次,因为您将fun()放在模块的顶层,因此它会在@patch导入tstmock时运行,然后再次正常运行。您应该将此调用包装在if __name__ == '__main__':块中(解释为here)。

...original code...

if __name__ == "__main__":
    fun()

答案 1 :(得分:0)

非常感谢您提供的输入,我设法通过更改代码来开始工作,如下所示。

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()

然而,即使我修补了功能日志,它也会被调用并生成在输出

之下
+++ Hello
Hello