2010-07-19 49 views
1

我的python应用程序使用urllib2向很多urls发出很多http请求。我想构建一个单元测试套件来测试我的数据解析和错误处理代码。测试urllib2应用程序,从文件加载的http响应

我有一个充满测试数据的目录,其中包含大量文件,每个文件都包含一个http响应,包含标题和响应数据。 (使用curl -i)在某些情况下,这些文件包含http错误消息(需要测试错误处理)

理想情况下,我想创建一个模拟对象来替换urllib2.urlopen并返回一个模拟响应对象。

我想知道如果有一个简单的方法有直接的urllib2从文件加载的HTTP响应,并具有urllib2的解析这个数据来创建相应的响应对象(好像响应是从URL中读取。

我尝试使用的URL与构建“文件://”的协议,但HTTP响应头在文件的顶部不读也不能正确解析

或者我正在考虑写一个小web服务器类服务。测试文件,但是这似乎比我想要的多一点工作,让urllib2以某种方式重建我已经保存在文件中的http响应的响应对象会更容易(不必建立一个Web服务器再次提供服务)

任何想法?

回答

2

我认为最好的办法是嘲弄的httplib.HTTPConnection一个子集(拨打以下为具体结果类mockcon),并添加使用它,子类HTTPHandler(在build_opener使用一个处理程序 - 子类化意味着它可以更换HTTPHandlerbuild_opener默认使用):

class MockHTTPHandler(urllib2.HTTPHandler): 

    def http_open(self, req): 
     return self.do_open(mockcon, req) 

的mockcon类必须提供方法do_open呼叫 - 几个可以假人(即接受并忽略任意指定参数和kwds,什么也不做):

set_debuglevel 
_set_tunnel 
request 

(可能对request的第二个参数感兴趣,因为它给出URL的“选择器”部分)。

mockcon__init__方法获取的URL的主机部分作为第一个参数(即,第一当然self后),并应忽略以下kwds(用于设置一个超时)。

mockconget_response方法(无参数,超越当然self的)必须返回一个HTTP响应对象 - 即一个类文件读取的对象也具有属性.msg.status,和.reason和方法get_full_url()到返回URL。

你可以使用一个实际httplib.HTTPResponse实例为后者的角色,但你必须有一个makefile争论一个模拟/虚拟ARG初始化(忽略其指定参数和kwds和回报等等),并对其进行初始化之后,将其.fp参数重置为rb打开的文件,准确给出真正的HTTP响应在其套接字上接收的字节。

我认为,建立一个完整的Mock整个urllib2.urlopen调用可能会比这个尝试再使用大多数的urllib2(和它内部使用httplib)的功能比较简单,虽然也许不是很简单的“本地网络服务器“的方法,你似乎认为是更多的工作。但值得考虑所有三种方法(模拟肯定会是最轻量级/快速的操作,本地Web服务器最慢......并且还需要以某种方式通过在它们前面加上http://localhost:someport/来修改URL)。

1

服务器方法绝对不是更多的工作,它可能是所有替代方案中最简单和最少的工作。

退房:http://docs.python.org/library/simplehttpserver.html

从某个目录运行将成为了所有的文件(递归,任何文件子目录)over HTTP时,有7行Python程序。

您或许可以让您的单元测试代码启动和停止服务器,以便即使未测试时也不需要保持运行状态。

+0

尽管对于简单的测试来说很容易,但对于*单元测试来说,启动服务器通常不是一个好的方法(一个新的进程),嘲笑外部实体和功能是最好的方法。对于许多其他类型的测试,这是一个不错的选择。一个原因不是太强大,但downvote! – 0xc0de 2015-12-02 09:38:52

+0

我同意,一个适当的模拟解决方案将更好地整体工作。我只是在回应这样的陈述,即做太多的工作。就快速启动和运行而言,这可能是最简单的事情。从长远来看,这绝对不是最好的,我根本就没有争论过 – entropy 2015-12-03 10:46:17

相关问题