How do you test a function using which retrieves data by urllib2?
I am getting into testing in python and I asked myself how to test this method.
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
Using doctest 开发者_如何学编程or unittest, how is this best achieved? I thought of passing get_response()
a test url and some test parameters, which exists in real world and to check if response.read()
returns the expected data. But somehow I feel, this is not the way it should be done. Any suggestions? I would appreciate suggestions how to handle such cases in context of texting.
This is a good case for using fake objects:
# 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"
This is just the sketchiest sketch of how you could override the real urllib2.urlopen function with your own fake implementation to test your code without really hitting the web.
This is a good opportunity to use a mock testing framework, such as 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
Do note that the unit is embedded in the docstring for the function under test, in doctest format.
精彩评论