【发布时间】:2014-11-05 15:12:04
【问题描述】:
我有一个带有昂贵 __init__ 函数的课程。我不想从测试中调用这个函数。
出于本示例的目的,我创建了一个在__init__ 中引发异常的类:
class ClassWithComplexInit(object):
def __init__(self):
raise Exception("COMPLEX!")
def get_value(self):
return 'My value'
我有第二个类,它构造ClassWithComplexInit 的实例并使用它的函数。
class SystemUnderTest(object):
def my_func(self):
foo = ClassWithComplexInit()
return foo.get_value()
我正在尝试围绕SystemUnderTest#my_func() 编写一些单元测试。我遇到的问题是,无论我如何尝试模拟 ClassWithComplexInit,__init__ 函数总是会被执行并引发异常。
class TestCaseWithoutSetUp(unittest.TestCase):
@mock.patch('mypackage.ClassWithComplexInit.get_value', return_value='test value')
def test_with_patched_function(self, mockFunction):
sut = SystemUnderTest()
result = sut.my_func() # fails, executes ClassWithComplexInit.__init__()
self.assertEqual('test value', result)
@mock.patch('mypackage.ClassWithComplexInit')
def test_with_patched_class(self, mockClass):
mockClass.get_value.return_value = 'test value'
sut = SystemUnderTest()
result = sut.my_func() # seems to not execute ClassWithComplexInit.__init__()
self.assertEqual('test value', result) # still fails
# AssertionError: 'test value' != <MagicMock name='ClassWithComplexInit().get_value()' id='4436402576'>
上面的第二种方法是我从this similar Q&A 得到的,但它也不起作用。 似乎没有运行 __init__ 函数,但我的断言失败了,因为结果最终是一个模拟实例,而不是我的值。
我还尝试在setUp 函数中配置patch 实例,将start 和stop 函数用作the docs suggest。
class TestCaseWithSetUp(unittest.TestCase):
def setUp(self):
self.mockClass = mock.MagicMock()
self.mockClass.get_value.return_value = 'test value'
patcher = mock.patch('mypackage.ClassWithComplexInit', self.mockClass)
patcher.start()
self.addCleanup(patcher.stop)
def test_my_func(self):
sut = SystemUnderTest()
result = sut.my_func() # seems to not execute ClassWithComplexInit.__init__()
self.assertEqual('test value', result) # still fails
# AssertionError: 'test value' != <MagicMock name='mock().get_value()' id='4554658128'>
这似乎也避免了我的__init__ 函数,但我为get_value.return_value 设置的值没有得到尊重,get_value() 仍然返回一个MagicMock 实例。
如何模拟具有复杂__init__ 的类,该类由我的测试代码实例化?理想情况下,我想要一个适用于 TestCase 类中的许多单元测试的解决方案(例如,不需要 patch 每次测试)。
我正在使用 Python 版本2.7.6。
【问题讨论】:
-
如何使
ClassWithComplexInit可用于您的测试脚本?from mypackage import ClassWithComplexInit,还是别的什么? -
@chepner 我的测试脚本甚至没有导入
ClassWithComplexInit。我将一堆代码从我的真实代码中切换到此处发布在 SO 上并弄乱了包引用,我意识到引用是错误的。不过,您在回答中解决了这个问题,谢谢!
标签: python python-2.7 mocking python-unittest python-mock