【问题标题】:In Python, are there any libraries that mock out responses for httplib?在 Python 中,是否有任何库可以模拟 httplib 的响应?
【发布时间】:2013-09-15 16:12:48
【问题描述】:

我目前正在使用 python_flickr_api 为我的应用上传照片:它使用 httplib 执行多部分 POST 请求。

问题:我想通过拦截 POST 请求并创建预先设置的成功响应来验证上传确实是在集成测试中发出的,这样我的测试就可以完全离线运行而不依赖于 Flickr(我不也想上传同一张测试图片 100 次!)

为此,我尝试使用两个令人难以置信的库:VCRPyHTTPretty。它们都没有解决我的问题,因为它们都不支持httplib(HTTPretty 最接近,仅支持httplib2),并且我收到一个看起来像这样的错误:

 Failure/Error: [Errno 32] Broken pipe

 Traceback:
 ...
 File "/usr/local/lib/python2.7/site-packages/flickr_api/upload.py", line 92, in upload
     r = post(UPLOAD_URL,auth.AUTH_HANDLER,args,photo_file)
 File "/usr/local/lib/python2.7/site-packages/flickr_api/upload.py", line 52, in post
     r = multipart.posturl(url,fields,files)
 File "/usr/local/lib/python2.7/site-packages/flickr_api/multipart.py", line 19, in posturl
     return post_multipart(urlparts[1], urlparts[2], fields,files)
 File "/usr/local/lib/python2.7/site-packages/flickr_api/multipart.py", line 33, in post_multipart
     h.send(body)
 File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 805, in send
     self.sock.sendall(data)
 File "/usr/local/lib/python2.7/site-packages/httpretty/core.py", line 243, in sendall
     return self._true_sendall(data)
 File "/usr/local/lib/python2.7/site-packages/httpretty/core.py", line 216, in _true_sendall
     self.truesock.sendall(data, *args, **kw)
 File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 224, in meth
     return getattr(self._sock,name)(*args)

很明显httpretty 正在拦截但导致管道损坏。

我该如何解决这个问题?

【问题讨论】:

  • 我想继续使用 flickr_api 来实现这个功能,因为它为我处理了像 OAuth 这样的讨厌的事情。我想使用FakeWeb-esque 库进行测试,因为我不想将我的测试耦合到flickr_api
  • 你能把测试和你正在测试的方法显示出来,我可以帮你写一个Mock。
  • 嗯,上传就一行。 flickr.upload(photo_file="/path/to/foobar.jpg", title="foobar") 但是你为此编写一个模拟非常简单,但正如我所说,我不想将我的测试与python_flickr_api 的界面结合起来。

标签: python mocking httplib fakeweb


【解决方案1】:

我是VCR.py 的作者。我想我可能已经修复了阻止 VCR 使用您正在使用的 flickr API 库的错误。尝试在fix-flickr-api branch 中安装该版本,让我知道这是否适合您。

【讨论】:

  • 谢谢,我试试看。
【解决方案2】:

您为什么不编写一个简单的 WSGI 服务器来打印您需要的内容?

例如,以下代码(仅使用 Python 标准库):

def application(environ, start_response):
    print environ
    status = "200 OK"
    headers = [("Content-Type", "text/plain"),
               ("Content-Length", "0")]
    start_response(status, headers)
    return ""

if __name__ == "__main__":
    from wsgiref.simple_server import make_server
    httpd = make_server("localhost", 8080, application)
    httpd.serve_forever()

将在屏幕上打印请求的环境(请求方法、url 等内容)。您也可以非常简单地打印请求正文等。

在您的 flickr 应用程序中,只需将 URL 替换为 localhost:8080 并向您自己的计算机发出请求。

【讨论】:

  • 嗯,我真的希望重量更轻一些。除了模拟之外,设置服务器似乎是必要的。
  • 少于 10 行?
  • 如果您正在查看内存成本,是的,10 行代码几乎只有 0.5kB — 但当然这需要集成到 bash 脚本或集成测试文件中,这将添加一个进一步的6-10行。启动测试有开销,因为我需要管理一个资源:端口 8080(想象其中两个同时运行......)测试更难编写,因为为所有人重用相同类型的服务器并非易事测试响应......这个列表还在继续;我的意思是“重量更轻”,因为从长远来看,维护成本更低。
  • 而且它的可读性不如其他潜在解决方案,这对我来说是个大问题,尤其是在测试方面。
  • 我想我们对 Python 和 Web 开发的理解不同。和平。
【解决方案3】:

有大量此类功能的库,请查看Mock

但看起来您正在寻找类似于 FakeWeb 的东西,所以我会结帐 HTTPretty

看来您已经尝试过 HTTPretty。我将模拟 flickr_api 进行的方法调用,并让它返回一个包含您期望的有效负载的存根。

祝你好运。

【讨论】:

  • 是的,我想我可能已经用尽了这方面的选项。这表明我应该尝试以不同的方式执行上传。
猜你喜欢
  • 2011-03-22
  • 1970-01-01
  • 2010-12-18
  • 2011-09-08
  • 2023-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多