我有一个__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'>
上面的第二种方法是我从这个类似的问答中得到的,但它也不起作用。它似乎没有运行该__init__
函数,但我的断言失败了,因为结果最终是一个模拟实例,而不是我的值。
我还尝试patch
在函数中配置一个实例setUp
,使用文档建议start
的andstop
函数。
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
。