Python中是否有任何库可以模拟httplib的响应?

3
我目前正在使用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 的库进行测试,因为我不想让测试与 flickr_api 相耦合。 - fatuhoku
你能展示一下你正在测试的测试和方法吗?我可以帮你编写一个 Mock。 - Mahdi Yusuf
嗯,上传只需要一行代码。 flickr.upload(photo_file="/path/to/foobar.jpg", title="foobar")但是编写一个模拟程序非常简单,就像我说的那样,我不想把我的测试与 python_flickr_api 的接口耦合在一起。 - fatuhoku
3个回答

5

我是VCR.py的作者。我认为我可能已经修复了阻止VCR与您正在使用的flickr API库一起工作的错误。请尝试安装fix-flickr-api分支中的版本,并让我知道是否有效。


1
为什么不编写一个简单的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并向自己的计算机发出请求即可。


哎呀,我真的希望有轻量级的解决方案。除了模拟之外,似乎还需要搭建一个服务器。 - fatuhoku
小于大约10行? - Escualo
1
如果你关注内存成本,那么10行代码只有0.5kB的大小——但当然这需要集成到bash脚本或集成测试文件中,这将再增加6-10行。启动测试存在开销,因为我需要管理一个资源:端口8080(想象一下同时运行两个这样的端口……)编写测试更加困难,因为重用相同类型的服务器以响应所有测试并不容易……这个列表还可以继续下去;我的意思是“轻量级”指的是长期维护成本更低。 - fatuhoku
而且它不像其他潜在的解决方案那样易读,这对我来说是不能接受的,特别是在测试方面。 - fatuhoku
我想我们对Python和Web开发有不同的理解。祝好。 - Escualo

1

有很多库可以实现这种功能,请查看Mock

但是看起来你正在寻找类似于FakeWeb的东西,所以我建议你查看HTTPretty

考虑到您已经尝试过HTTPretty。我会模拟 flickr_api 调用的方法,并返回一个带有预期负载的存根。

祝你好运。


是的,我猜我可能已经尝试过所有选项了。这告诉我应该尝试以不同的方式执行上传。 - fatuhoku

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接