我在应用程序的一种方法中使用Python的请求库。该方法的主体如下所示:
def handle_remote_file(url, **kwargs): response = requests.get(url, ...) buff = StringIO.StringIO() buff.write(response.content) ... return True
我想为该方法编写一些单元测试,但是,我想做的是传递一个伪本地URL,例如:
class RemoteTest(TestCase): def setUp(self): self.url = 'file:///tmp/dummy.txt' def test_handle_remote_file(self): self.assertTrue(handle_remote_file(self.url))
当我使用本地URL调用 requests.get 时,出现以下 KeyError 异常:
requests.get('file:///tmp/dummy.txt') /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/packages/urllib3/poolmanager.pyc in connection_from_host(self, host, port, scheme) 76 77 # Make a fresh ConnectionPool of the desired type 78 pool_cls = pool_classes_by_scheme[scheme] 79 pool = pool_cls(host, port, **self.connection_pool_kw) 80 KeyError: 'file'
问题是如何将本地URL传递给 request.get ?
PS:我整理了上面的示例。它可能包含许多错误。
正如@WooParadog解释的那样,请求库不知道如何处理本地文件。虽然,当前版本允许定义传输适配器。
因此,您只需定义自己的适配器即可处理本地文件,例如:
from requests_testadapter import Resp class LocalFileAdapter(requests.adapters.HTTPAdapter): def build_response_from_file(self, request): file_path = request.url[7:] with open(file_path, 'rb') as file: buff = bytearray(os.path.getsize(file_path)) file.readinto(buff) resp = Resp(buff) r = self.build_response(request, resp) return r def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): return self.build_response_from_file(request) requests_session = requests.session() requests_session.mount('file://', LocalFileAdapter()) requests_session.get('file://<some_local_path>')
在上面的示例中,我使用了requests-testadapter模块。