我正在为我的模块创建一个使用请求库的测试套件。但是,我正在尝试为特定请求模拟几个不同的返回值,而我却遇到了麻烦。这是我的代码片段不起作用:
class MyTests(unittest.TestCase):
@patch('mypackage.mymodule.requests.post')
def test_change_nested_dict_function(self, mock_post):
mock_post.return_value.status_code = 200
mock_post.return_value.json = nested_dictionary
modified_dict = mymodule.change_nested_dict()
self.assertEqual(modified_dict['key1']['key2'][0]['key3'], 'replaced_value')
我试图模仿的功能:
import requests
def change_nested_dict():
uri = 'http://this_is_the_endpoint/I/am/hitting'
payload = {'param1': 'foo', 'param2': 'bar'}
r = requests.post(uri, params=payload)
# This function checks to make sure the response is giving the
# correct status code, hence why I need to mock the status code above
raise_error_if_bad_status_code(r)
dict_to_be_changed = r.json()
def _internal_fxn_to_change_nested_value(dict):
''' This goes through the dict and finds the correct key to change the value.
This is the actual function I am trying to test above'''
return changed_dict
modified_dict = _internal_fxn_to_change_nested_value(dict_to_be_changed)
return modified_dict
我知道这样做的一个简单方法就是没有嵌套函数,但我只是向你展示整个函数代码的一部分。相信我,嵌套函数是必要的,我真的不想改变它的那一部分。
我的问题是,我不明白如何模拟requests.post然后设置状态代码和内部json解码器的返回值。我也似乎找不到解决这个问题的方法,因为我似乎无法修补内部函数,这也可以解决这个问题。有没有人有任何建议/想法?非常感谢。
答案 0 :(得分:4)
我碰到了这里,尽管我同意可能使用特殊用途的库是一个更好的解决方案,但最终我还是做了以下
from mock import patch, Mock
@patch('requests.post')
def test_something_awesome(mocked_post):
mocked_post.return_value = Mock(status_code=201, json=lambda : {"data": {"id": "test"}})
这对我有用,因为在进行单元测试时,在接收器端同时获取了status_code
和json()
。
在这里写上以为有人可能会有所帮助。
答案 1 :(得分:3)
当您mock
将每个子方法设置为一个新的MagicMock
时,需要对其进行配置。因此,在这种情况下,您需要为return_value
设置mock_post
以使子属性生效,和实际返回一个,即:
mock_post.return_value.status_code.return_value = 200
mock_post.return_value.json.return_value = nested_dictionary
你可以通过查看所有内容的类型来看到这一点:
print(type(mock_post))
print(type(mock_post.json))
在这两种情况下,类型都是<class 'unittest.mock.MagicMock'>
答案 2 :(得分:1)