我正在尝试使用模拟python库,并决定使用装饰器来隐藏一些重复操作,以便使用相应的替换方法设置模拟side_effect变量。
到目前为止,我有以下代码,它没有进入测试,它基本上什么也没做。有想法该怎么解决这个吗?谢谢!
import unittest
from mock import patch
# Replacement method for requests.get call
def mock_requests_get(url=None, **kwargs):
if url == URL1:
return {'url':url, 'status_code':200, 'status':'success'}
if url == URL2: A
return {'url':url, 'status_code':403}
# Replacement method for requests.post call
def mock_requests_post(url, data=None, **kwargs):
if url == URL1 and data['data']=='go':
return {'url':url, 'status_code':200, 'status':'success'}
if url == URL2 and data['data']!='gogo':
return {'url':url, 'status_code':403}
# Decorator which sets mock replacement methods
def mock_type(method=''):
def _mock(func):
def _decorator(mock_get, mock_post, *args, **kwargs):
print method
if method == 'GET':
mock_get.side_effect = mock_requests_get
if method == 'POST':
mock_post.side_effect = mock_requests_post
func(mock_get, mock_post, *args, **kwargs)
return _decorator
return _mock
@patch('requests.post')
@patch('requests.get')
class TestKeywordsApi(unittest.TestCase):
def setUp(self):
self.ka = KeywordsApi()
@mock_type('GET')
def test_get(self, mock_get, mock_post):
# Replace this code in mock_type decorator:
#mock_get.side_effect=mock_requests_get
print self.ka.get(URL1)
print self.ka.get(URL2)
# Do asserts
@mock_type('POST')
def test_post(self, mock_get, mock_post):
# Replace this code in mock_type decorator:
#mock_post.side_effect=mock_requests_post
print self.ka.post(URL1, {'data':'go'})
print self.ka.post(URL2, {'data':'go'})
# Do asserts
答案 0 :(得分:2)
确保替换执行命名空间中的函数。根据导入,您当前的代码可能会或可能不会替换您认为它正在替换的内容。以下是我认为您试图做的事情。
import kwmodule
import unittest, mock
def mock_requests_get(url=None, **kwargs):
"Replacement method for requests.get call"
pass
def mock_requests_post(url, data=None, **kwargs):
"Replacement method for requests.post call"
pass
@mock.patch('kwmodule.requests.post', mock_requests_post)
@mock.patch('kwmodule.requests.get', mock_requests_get)
class TestKeywordsApi(unittest.TestCase):
def setUp(self):
self.ka = kwmodule.KeywordsApi()
然而,您可能更成功地更换了get&发布自动指定的MagicMock对象。如果这对您不起作用,则使用您自己的自定义替换。
例如,如果您知道调用“get。”的顺序,则以下补丁装饰器将起作用。
return_values = [{'url':url, 'status_code':200, 'status':'success'},
{'url':url, 'status_code':403},
AssertionError('Unexpected call.')]
@mock.patch('kwmodule.requests.get', autospec=True, side_effect=return_values)
这将在第一次调用时返回“success”条件,第二次返回错误,如果第三次调用它将引发AssertionError。十分之九,我使用side_effect而不是编写自己的返回生成函数。