如何测试通过urllib2获取数据的函数?

7 投票
2 回答
888 浏览
提问于 2025-04-16 21:38

我正在学习如何在Python中进行测试,心里想怎么测试这个方法。

def get_response(self, url, params):
    encoded_params = urllib.urlencode(params)
    request = urllib2.Request(BASE_URL, headers=HEADERS)
    response = urllib2.urlopen(request, encoded_params)
    return response

使用doctest或unittest,这样做最有效吗?我想过给get_response()传一个测试用的URL和一些测试参数,这些在现实中是存在的,然后检查response.read()是否返回了预期的数据。但是我总觉得,这样做不太对。有没有什么建议?我希望能得到一些关于如何在测试中处理这种情况的建议。

2 个回答

5

这是一个使用假对象的好例子:

# my_module
get_url = urllib2.urlopen

def get_response(self, url, params):
    encoded_params = urllib.urlencode(params)
    request = urllib2.Request(BASE_URL, headers=HEADERS)
    response = get_url(request, encoded_params)
    return response

# test_my_module    
def fake_get_url(request, params):
    assert request == "the url I expect"
    assert params == ['the', 'params', 'i', 'expect']
    return SomeFakeResponse("OK")

my_module.get_url = fake_get_url
assert my_module.get_response("blah", "blah").content == "OK"

这只是一个非常简单的示例,展示了你如何用自己的假实现来替代真正的urllib2.urlopen函数,这样你就可以测试你的代码,而不需要真的去访问网络。

3

这是一个很好的机会,可以使用一个模拟测试框架,比如minimock

BASE_URL='http://google.com'
HEADERS = {"accept-language":"klingon"}
import urllib, urllib2
def get_response(self, url, params):
    r"""
    >>> from minimock import Mock
    >>> urllib2.Request = Mock('urllib2.Request')
    >>> urllib2.urlopen = Mock('urllib2.urlopen')
    >>> get_response(None, 'http://google.com', {'foo':'bar'})
    Called urllib2.Request(
        'http://google.com',
        headers={'accept-language': 'klingon'})
    Called urllib2.urlopen(None, 'foo=bar')
    >>> 
    """
    encoded_params = urllib.urlencode(params)
    request = urllib2.Request(BASE_URL, headers=HEADERS)
    response = urllib2.urlopen(request, encoded_params)
    return response

请注意,单元测试是嵌入在被测试函数的文档字符串中的,格式是doctest

撰写回答