使用request_mock和pytest模拟botocore.vendored请求

时间:2018-11-14 19:11:47

标签: python python-requests boto3

我正在尝试用requests_mock模拟一个get请求,但似乎并不能解决问题。

我的函数调用文件lookup.py中定义的第三方API:

from botocore.vendored import requests

def get_data():
   url = 'https://abc.something.com/datapackage'
   url_params={
      'v': 2,
      'auth_apikey':'xyz'
   }
   resp = requests.get(url, params=url_params)
   return resp.json()

我正在使用py.test来运行测试并在测试文件中运行。我有个固定装置:

  import requests_mock
  import requests, pytest
  from lookup import get_data

  @pytest.fixture
  def req_mock(request):
    m = requests_mock.Mocker()
    m.start()
    request.addfinalizer(m.stop)
    return m

  def test_api_gets_data(req_mock):
      sample={
          'key1':123
      }
      lookup_url = 'https://abc.something.com/datapackage'
      query_params = {
        'v': 2,
        'auth_apikey':'xyz'
      }
      req_mock.get(lookup_url, json=sample)
      resp = get_data()

显然,requests_mock无法与get函数中的请求使用相同的会话,因此不会受到嘲笑。

有更好的方法吗?

我正在使用Python 3.6,请求2.18,请求模拟1.52和pytest 3.0.7。

2 个答案:

答案 0 :(得分:0)

lookup.py个文件中,lookup_urlraise NameError导致名称lookup_url未定义。

使用url且不要忘记更改params=url_params,因此代码将如下所示:

resp = requests.get(url, params=url_params)

答案 1 :(得分:0)

显然,您无法使用from botocore.vendored import requests来嘲笑requests_mock

请改为使用unittest.mock模拟响应。

  from unittest import mock

  class MockResponse:
    def __init__(self, status_code, json_data=None):
      self.json_data = json_data
      self.status_code = status_code

   def json(self):
      return self.json_data

   def raise_for_status(self):
      if self.status_code >= 500:
        raise Exception

 item_not_found = {
    "Response": {
      "StatusCode": "ItemNotFound",
    }
 }

 item_not_found_resp = MockResponse(200, item_not_found)


 @mock.patch('botocore.vendored.requests.get', return_value=item_not_found_resp)
 def test_api_returns_not_found_when_third_party_api_returns_item_not_found(mc):
     resp = get(e1, c)
     exp_resp = {
       "statusCode": 404,
       "body": json.dumps({
        'error': 'no item found'
       })
     }
   request_url = mc.call_args[0][0]
   request_params = mc.call_args[1]['params']
   assert lookup_url == request_url
   assert query_params == request_params
   assert exp_resp == resp