模拟 requests.post 和 requests.json 解码器 python

新手上路,请多包涵

我正在为我的模块创建一个测试套件,它大量使用请求库。但是,我正在尝试为特定请求模拟几个不同的返回值,但我在这样做时遇到了麻烦。这是我不起作用的代码片段:

 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 解码器设置返回值。我似乎也找不到解决此问题的方法,因为我似乎也无法修补内部功能,这也可以解决此问题。有人有什么建议/想法吗?非常感谢。

原文由 the_deuce 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 513
2 个回答

当你 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'>

原文由 match 发布,翻译遵循 CC BY-SA 3.0 许可协议

我碰到这里虽然我同意可能使用特殊用途的库是一个更好的解决方案,但我最终还是做了以下事情

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_codejson()

写在这里认为有人可能会觉得它有帮助。

原文由 SRC 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题