我的項目使用Python的urllib2.urlopen
對外部API進行了各種調用。我正在使用NoseTests進行單元測試,MiniMock模擬urllib2.urlopen
的呼叫。如何向Python中的模擬函數提供條件參數?
嘲諷代碼:
from hashlib import md5
from os.path import dirname, join
from urllib2 import Request, urlopen
from minimock import mock, restore
def urlopen_stub(url, data=None, timeout=30):
"""
Mock urllib2.urlopen and return a local file handle or create file if
not existent and then return it.
"""
if isinstance(url, Request):
key = md5(url.get_full_url()).hexdigest()
else:
key = md5(url).hexdigest()
data_file = join(dirname(__file__), 'cache', '%s.xml' % key)
try:
f = open(data_file)
except IOError:
restore() # restore normal function
data = urlopen(url, data).read()
mock('urlopen', returns_func=urlopen_stub, tracker=None) # re-mock it.
with open(data_file, 'w') as f:
f.write(data)
f = open(data_file, 'r')
return f
mock('urlopen', returns_func=urlopen_stub, tracker=None)
我跑我的測試,像這樣:
from os.path import isfile, join
from shutil import copytree, rmtree
from nose.tools import assert_raises, assert_true
import urlopenmock
class TestMain(object):
working = 'testing/working'
def setUp(self):
files = 'testing/files'
copytree(files, self.working)
def tearDown(self):
rmtree(self.working)
def test_foo(self):
func_a_calling_urlopen()
assert_true(isfile(join(self.working, 'file_b.txt')))
def test_bar(self):
func_b_calling_urlopen()
assert_true(isfile(join(self.working, 'file_b.txt')))
def test_bar_exception(self):
assert_raises(AnException, func_c_calling_urlopen)
我原本的測試檢查在一個單獨的模塊除外,它導入了不同嘲諷文件當調用urlopen
時,它返回一個破損的XML文件。但是,導入該模擬類會覆蓋上面顯示的類,因爲每次都會使用損壞的XML來打破所有測試。
我認爲這是因爲異常測試模塊被加載到其他模塊之後,因此它的導入被稱爲last,並且模擬的函數返回破損的XML覆蓋原始的模擬函數。
我希望能夠告訴模擬代碼在運行test_bar_exception時使用破損的XML文件,以便引發異常。我會如何去做這件事?
爲Python一個偉大的模擬系統,請查看[Fudge](http://farmdev.com/projects/fudge/)。 – 2011-05-01 00:19:52