gpt4 book ai didi

python - 如何为 Python 中的模拟函数提供条件参数?

转载 作者:太空宇宙 更新时间:2023-11-04 01:40:17 25 4
gpt4 key购买 nike

我的项目使用 Python 的 urllib2.urlopen 对外部 API 进行各种调用。我使用 NoseTests 进行单元测试,使用 MiniMock 模拟对 urllib2.urlopen 的调用。

模拟代码:

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,所以会破坏所有测试。

我假设这是因为异常测试模块是在其他模块之后加载的,因此它的导入最后被调用,并且返回损坏的 XML 的模拟函数覆盖了原始模拟函数。

我希望能够在运行 test_bar_exception 时告诉模拟代码使用损坏的 XML 文件,以便引发异常。我该怎么做呢?

最佳答案

在我看来,您需要在每个需要使用它的测试上设置和拆除您的模拟 urlopen,并使用不同的模拟 urlopen 为那些处理该错误情况的测试返回损坏的 xml 文件。像这样的东西:

class TestMain(object):
# ...

def test_foo(self):
mock('urlopen', returns_func=urlopen_stub, tracker=None)
func_a_calling_urlopen()
assert_true(isfile(join(self.working, 'file_b.txt')))
restore()

# ...

def test_bar_exception(self):
mock('urlopen',
returns_func=urlopen_stub_which_returns_broken_xml_file,
tracker=None)
assert_raises(AnException, func_c_calling_urlopen)
restore()

但是,如果测试引发异常并且未达到 restore() 调用,则上述情况存在问题。您可以用 try: ... finally: 包装,但是,每个测试都有很多繁文缛节。

您可能想看看 Michael Foord 的 mock图书馆。

Pycon 演示:http://blip.tv/file/4881513

看看patch它为您提供装饰器和上下文管理器选项,用于替换和恢复您对 urlopen 的调用。非常漂亮!

关于python - 如何为 Python 中的模拟函数提供条件参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5843938/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com