如何模拟包的模块中定义的函数?

zal*_*lun 44 python mocking

我有一个以下结构:

|-- dirBar
|   |-- __init__.py
|   |-- bar.py
|-- foo.py
`-- test.py
Run Code Online (Sandbox Code Playgroud)

bar.py

def returnBar():
    return 'Bar'
Run Code Online (Sandbox Code Playgroud)

foo.py

from dirBar.bar import returnBar

def printFoo():
    print returnBar()
Run Code Online (Sandbox Code Playgroud)

test.py

from mock import Mock

from foo import printFoo
from dirBar import bar

bar.returnBar = Mock(return_value='Foo')

printFoo()
Run Code Online (Sandbox Code Playgroud)

结果python test.pyBar.

如何模拟printBar使其返回Foo以便printFoo打印出来?

编辑:没有修改任何其他文件 test.py

num*_*er5 37

我猜你要模拟这个函数returnBar,你想使用patch装饰器:

from mock import patch

from foo import printFoo

@patch('foo.returnBar')
def test_printFoo(mockBar):
    mockBar.return_value = 'Foo'
    printFoo()

test_printFoo()
Run Code Online (Sandbox Code Playgroud)

  • 缺少的部分是你在导入**的地方修补功能,而不是从*导入的地方*.在`foo.py`中导入`from dirBar.bar import returnBar`之后,模拟需要将导入修补为`foo.returnBar`,而不是`dirBar.bar.returnBar`. (11认同)
  • @hughdbrown`基本原则是在查找对象的位置打补丁,这不一定与定义它的位置相同。几个例子将有助于澄清这一点。` http://www.voidspace.org.uk/python/mock/patch.html#id1 (3认同)

bra*_*zzi 28

只需在bar模块之前导入foo模块并模拟它:

from mock import Mock

from dirBar import bar
bar.returnBar = Mock(return_value='Foo')

from foo import printFoo

printFoo()
Run Code Online (Sandbox Code Playgroud)

导入returnBarin时foo.py,将模块的值绑定到名为的变量returnBar.这个变量是本地的,因此在导入printFoo()时放入函数的闭包中foo- 并且闭包中的值不能通过代码来更新.因此,它应该在导入之前具有新值(即模拟函数)foo.

编辑:以前的解决方案工作但不健全,因为它取决于订购导入.那不太理想.另一个解决方案(在第一个解决方案之后发生)是导入bar模块foo.py而不是仅导入returnBar()函数:

from dirBar import bar

def printFoo():
    print bar.returnBar()
Run Code Online (Sandbox Code Playgroud)

这将起作用,因为returnBar()现在直接从bar模块而不是闭包中检索.因此,如果我更新模块,将检索新功能.