【问题标题】:Mocking urllib.request.urlopen using unittest使用 unittest 模拟 urllib.request.urlopen
【发布时间】:2021-12-18 12:04:00
【问题描述】:

我正在尝试模拟这个 urlopen 函数。从其他类似问题中得到了几个解决方案,但似乎都没有。

def lambda_handler(event, context):
   try:
        request = urllib.request.Request(url = URL, data = data, method = method, headers = headers)
        with urllib.request.urlopen(request) as httpResponse:
            # print(httpResponse.read().decode('utf-8'))
            string = httpResponse.read().decode('utf-8')
            response = json.loads(string)
            print(response)
            return response

尝试的方法:

class mock_request():
   class Request():
       ....
   def urlopen(*args, **krwargs):
       return {}

@mock.patch(.....urllib.request, mock_request)

【问题讨论】:

    标签: request mocking urllib python-unittest


    【解决方案1】:

    我认为最简单的方法是修补 __enter__ + __exit__ 方法。只是一个例子:

    def lambda_handler(event, context):
        try:
            # some request... just an example
            request = Request('https://restcountries.com/v3.1/name/belarus')
            with urllib.request.urlopen(request) as resp:
                string = resp.read().decode('utf-8')
                return json.loads(string)
        except Exception:
           pass
    

    测试:

    from unittest import TestCase, mock
    from unittest.mock import Mock
    
    
    class TestExample(TestCase):
        def test_lambda_handler(self):
            print(lambda_handler(1, 2))  # real result from restcountries
    
            open_mock = Mock(
                # resp.read().decode('utf-8') will return static value '[]'
                __enter__=Mock(return_value=Mock(read=Mock(return_value=Mock(decode=Mock(return_value='[]'))))),
                __exit__=Mock(),
            )
            with mock.patch('urllib.request.urlopen', return_value=open_mock):
                print(lambda_handler(1, 2))  # []
    
            # resp.read().decode('utf-8') will return dynamic values
            open_mock = Mock(
                __enter__=Mock(
                    return_value=Mock(
                        read=Mock(return_value=Mock(decode=Mock(side_effect=[
                            '[{"name": "N S"}]',
                            '[{"name": "D G"}]']
                        )))
                    )
                ),
                __exit__=Mock(),
            )
    
            with mock.patch('urllib.request.urlopen', return_value=open_mock):
                print(lambda_handler(1, 2))  # [{"name": "N S"}]
                print(lambda_handler(1, 2))  # [{"name": "D G"}]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-01
      • 1970-01-01
      • 2021-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-20
      • 2010-11-22
      相关资源
      最近更新 更多