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