Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing Python 3 urlopen上下文管理器模拟_Unit Testing_Python 3.x_Testing - Fatal编程技术网

Unit testing Python 3 urlopen上下文管理器模拟

Unit testing Python 3 urlopen上下文管理器模拟,unit-testing,python-3.x,testing,Unit Testing,Python 3.x,Testing,我是测试新手,这里需要一些帮助 假设有此方法: from urllib.request import urlopen def get_posts(): with urlopen('some url here') as data: return json.loads(data.read().decode('utf-8')) 问题是如何测试此方法(如果可能,使用mock.patch decorator) 我现在所拥有的: @mock.patch('mymodule.url

我是测试新手,这里需要一些帮助

假设有此方法:

from urllib.request import urlopen

def get_posts():
    with urlopen('some url here') as data:
        return json.loads(data.read().decode('utf-8'))
问题是如何测试此方法(如果可能,使用mock.patch decorator)

我现在所拥有的:

@mock.patch('mymodule.urlopen')
def test_get_post(self, mocked_urlopen):
    mocked_urlopen.__enter__ = Mock(return_value=self.test_data)
    mocked_urlopen.__exit__ = Mock(return_value=False)
    ...
但它似乎不起作用


另外,在测试中是否有任何方便的方法来处理数据变量(类型为HTTPResponse),以便它可以是简单的字符串?

好的,所以我编写了简单的类来模拟上下文管理器

class PatchContextManager:

    def __init__(self, method, enter_return, exit_return=False):
        self._patched = patch(method)
        self._enter_return = enter_return
        self._exit_return = exit_return

    def __enter__(self):
        res = self._patched.__enter__()
        res.context = MagicMock()
        res.context.__enter__.return_value = self._enter_return
        res.context.__exit__.return_value = self._exit_return
        res.return_value = res.context
        return res

    def __exit__(self, type, value, tb):
        return self._patched.__exit__()
用法:

with PatchContextManager('mymodule.method', 'return_string') as mocked:
    a = mymodule.method(47) # a == 'return_string'
    mocked.assert_called_with(47)
    ... 

我也在努力解决这个问题,最后终于解决了。(Python 3语法):


这是我对这件事的看法

from urllib.request import urlopen 
from unittest.mock import patch

class Mock():
    def __init__(self, request, context):
        return None

    def read(self):
        return self

    def decode(self, arg):
        return ''

    def __iter__(self):
        return self

    def __next__(self):
        raise StopIteration


 with patch('urllib.request.urlopen',  Mock):
    # do whatever over here

我不熟悉
mock
库,但也许您可以查看文档以了解更多详细信息。
self.test\u data
必须是具有
read()
方法的对象,而不是字符串。我可以问一下no\u cm和cm之间的区别吗?@EralpB cm表示他展示了一个使用urlopen作为上下文管理器的示例,no_cm展示了一个没有将其用作上下文管理器的示例。
from urllib.request import urlopen 
from unittest.mock import patch

class Mock():
    def __init__(self, request, context):
        return None

    def read(self):
        return self

    def decode(self, arg):
        return ''

    def __iter__(self):
        return self

    def __next__(self):
        raise StopIteration


 with patch('urllib.request.urlopen',  Mock):
    # do whatever over here