shr*_*ddd 60 python unit-testing mocking
我正在尝试使用python模块模块(http://www.voidspace.org.uk/python/mock/index.html)模拟一个函数(返回一些外部内容).
我在模拟导入模块的函数时遇到了一些麻烦.
例如,在util.py中我有
def get_content():
return "stuff"
Run Code Online (Sandbox Code Playgroud)
我想模拟util.get_content,以便返回其他内容.
我在尝试这个:
util.get_content=Mock(return_value="mocked stuff")
Run Code Online (Sandbox Code Playgroud)
如果get_content在另一个模块中调用它,它实际上似乎永远不会返回模拟对象.我是否错过了如何使用模拟的东西?
请注意,如果我调用以下内容,则可以正常工作:
>>> util.get_content=Mock(return_value="mocked stuff")
>>> util.get_content()
"mocked stuff"
Run Code Online (Sandbox Code Playgroud)
但是,如果从另一个模块内部调用get_content,它将调用原始函数而不是模拟版本:
>>> from mymodule import MyObj
>>> util.get_content=Mock(return_value="mocked stuff")
>>> m=MyObj()
>>> m.func()
"stuff"
Run Code Online (Sandbox Code Playgroud)
mymodule.py的内容
from util import get_content
class MyObj:
def func():
get_content()
Run Code Online (Sandbox Code Playgroud)
所以我想我的问题是 - 如何从我调用的模块中调用Mocked版本的函数?
这似乎from module import function可能是责备,因为它没有指向Mocked函数.
shr*_*ddd 28
我想我有一个解决方法,虽然我还不太清楚如何解决一般情况
在mymodule中,如果我更换
from util import get_content
class MyObj:
def func():
get_content()
Run Code Online (Sandbox Code Playgroud)
同
import util
class MyObj:
def func():
util.get_content()
Run Code Online (Sandbox Code Playgroud)
Mock似乎被调用了.看起来命名空间需要匹配(这是有道理的).然而,奇怪的是我会期待
import mymodule
mymodule.get_content = mock.Mock(return_value="mocked stuff")
Run Code Online (Sandbox Code Playgroud)
在我使用from/import语法(现在将get_content拉入mymodule)的原始情况下做的诀窍.但这仍然指的是未被嘲笑的get_content.
结果是命名空间很重要 - 只需要在编写代码时牢记这一点.
Sim*_*ijk 23
您必须修补使用它的功能.在你的情况下,将在mymodule模块中.
import mymodule
>>> mymodule.get_content = Mock(return_value="mocked stuff")
>>> m = mymodule.MyObj()
>>> m.func()
"mocked stuff"
Run Code Online (Sandbox Code Playgroud)
这里的文档中有一个参考:http://docs.python.org/dev/library/unittest.mock.html#where-to-patch
小智 12
一般情况下是使用patch从mock.考虑以下:
utils.py
def get_content():
return 'stuff'
Run Code Online (Sandbox Code Playgroud)
mymodule.py
from util import get_content
class MyClass(object):
def func(self):
return get_content()
Run Code Online (Sandbox Code Playgroud)
test.py
import unittest
from mock import patch
from mymodule import MyClass
class Test(unittest.TestCase):
@patch('mymodule.get_content')
def test_func(self, get_content_mock):
get_content_mock.return_value = 'mocked stuff'
my_class = MyClass()
self.assertEqual(my_class.func(), 'mocked stuff')
self.assertEqual(get_content_mock.call_count, 1)
get_content_mock.assert_called_once()
Run Code Online (Sandbox Code Playgroud)
注意如何get_content被嘲笑,它不是util.get_content,而是mymodule.get_content因为我们正在使用它mymodule.
上面已经用mock v2.0.0测试,nosetests v1.3.7和python v2.7.9.
我们假设您正在创建模拟内部模块foobar:
import util, mock
util.get_content = mock.Mock(return_value="mocked stuff")
Run Code Online (Sandbox Code Playgroud)
如果您在未先导入的情况下导入mymodule和调用,则不会安装您的模拟:util.get_contentfoobar
import util
def func()
print util.get_content()
func()
"stuff"
Run Code Online (Sandbox Code Playgroud)
代替:
import util
import foobar # substitutes the mock
def func():
print util.get_content()
func()
"mocked stuff"
Run Code Online (Sandbox Code Playgroud)
注意,foobar只要foobar在util.get_content调用之前进行评估,就可以从任何地方导入(模块A导入导入foobar的B).
| 归档时间: |
|
| 查看次数: |
49753 次 |
| 最近记录: |