避免执行模拟类的\uu init\uu

2024-10-01 19:23:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个类有一个昂贵的__init__函数。我不想从测试中调用这个函数。在

在这个例子中,我创建了一个在__init__中引发异常的类:

class ClassWithComplexInit(object):

    def __init__(self):
        raise Exception("COMPLEX!")

    def get_value(self):
        return 'My value'

我有第二个类,它构造ClassWithComplexInit的实例并使用它的函数。在

^{pr2}$

我正试图围绕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和{}函数作为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。在


Tags: 实例函数testselfgetreturninitvalue
2条回答

为什么不直接为测试创建子类并重写init呢?在

class testClassWithComplexInit(ClassWithComplexInit):
    def __init__(self):
        pass

ClassWithComplexInit = testClassWithComplexInit

现在,ClassWithComplexInit().get_value()返回'My value',而不是引发异常。在

首先,您需要使用与正在修补的名称相同的名称来创建foo,也就是说

class SystemUnderTest(object):

    def my_func(self):
        foo = mypackage.ClassWithComplexInit()
        return foo.get_value()

其次,您需要配置正确的模拟对象。您正在配置未绑定方法ClassWithComplexInit.get_value,但需要配置ClassWithComplexInit.return_value.get_value,这是一个Mock对象,该对象将被foo.get_value()调用。在

^{pr2}$

相关问题 更多 >

    热门问题