尝试理解模拟/修补,我有一个包含三个文件的宁静API项目(仅供参考,我正在使用烧瓶)
class1.py文件内容:
class one:
def addition(self):
return 4+5
domain.py文件内容:
from class1 import one
class DomainClass(Resource):
def post(self):
test1 = one()
val = test1.addition()
return {'test' : val }
test_domain.py文件内容:
import my_app
from flask_api import status
from mock import patch
app = my_app.app.test_client()
def test_post():
with patch('domain.one') as mock:
instance = mock.return_value
instance.addition.return_value = 'yello'
url = '/domain'
response = app.post(url)
print response.data
assert status.HTTP_200_OK == response.status_code
assert mock.called
对于我的test_domain.py文件,我也试过了......
@patch('domain.one')
def test_post(mock_domain):
mock_domain.addition.return_value = 1
url = '/domain'
response = app.post(url)
print response.data
assert status.HTTP_200_OK == response.status_code
我断言200次通过的状态,但是,问题是我无法模拟或修补添加方法以给我1的值代替9(4 + 5)。我也试过'断言mock.called',它也很脆弱。我知道我应该使用'one()'方法进行模拟/修补,即在domain.py中不在class1.py中。但是我甚至尝试用class1.one代替domain.one而且我仍然保持9而不是1.我做错了什么?
********更新 我在同一个问题上遇到了另一个困境,我尝试在test_domain文件中执行此操作而不是修补....
from common.class1 import one
def test_post():
one.addition = MagicMock(return_value=40)
url = '/domain'
response = app.post(url)
print response.data
assert status.HTTP_200_OK == response.status_code
问题
在上面的更新中,我没有在使用它的地方进行模拟(即:domain.one.addition = MagicMock(...),它仍然有用!!!!似乎它可能做一个全球变化。为什么这样做?
在上面的例子中,'one'是模块class1.py中的一个类。如果我将这个类'one'更改为class1.py中的函数,则mocking不起作用。似乎这个函数'one'驻留在模块class1.py中不能像这样嘲笑... one.return_value ='xyz',为什么?可以在全球范围内嘲笑吗?
答案 0 :(得分:2)
您的代码中存在一些问题。在第一个示例中,您忘记了在patch()
上下文中应用了with
,并且在上下文结束时恢复了原始代码。遵循代码应该工作:
def test_post():
with patch('domain.one') as mock:
instance = mock.return_value
instance.addition.return_value = 'yello'
url = '/domain'
response = app.post(url)
print response.data
assert status.HTTP_200_OK == response.status_code
assert mock.called
assert response.data['test'] == 'yello'
第二个问题还有另外一个问题:如果你想要补丁addition
方法,你应该使用:
@patch('domain.one.addition')
def test_post(mock_addition):
mock_addition.return_value = 1
...
assert mock_addition.called
assert response.data['test'] == 1
如果你想要模拟所有one
类,你应该设置addition
调用模拟实例的mock_domain
方法的返回值就像你的第一个例子:
@patch('domain.one')
def test_post(mock_domain):
mock_addition = mock_domain.return_value.addition
mock_addition.return_value = 1
...
assert mock_addition.called
assert response.data['test'] == 1