在TestCase.setUp()中进行模拟

时间:2014-08-16 08:51:28

标签: python unit-testing mocking

我想模仿TestCase的所有测试方法。

我第一次尝试使用TestCase.setUp()不起作用,因为setUp()在测试方法执行之前完成。

我无法在setUp()内部模拟真实的测试方法:

with mock.patch(...):
    do_something()

我想我错过了什么。

如何将mock.patch()用于测试用例的所有方法?

3 个答案:

答案 0 :(得分:5)

with mock.patch()上下文管理器,当上下文结束时,补丁未应用,上下文在代码块结束时结束。

这意味着当setUp()结束时,补丁不会再次应用。

您的选择是使用@mock.patch()作为类装饰器或使用修补程序上的start and stop methods

使用@mock.patch()作为类装饰器与将其作为装饰器应用于每个测试方法具有相同的效果:

@mock.patch('module.ClassName')
class TestFoo(unittest.TestCase):
    def setUp(self):
        # ...

    def test_one(self, class_mock):
        # ...

    def test_two(self, class_mock):
        # ...

此处test_onetest_two都在模拟对象中传递,因为@mock.patch()类装饰器找到了所有测试方法并对其进行了修饰。

使用启动和停止方法,您可以使用setUptearDown方法应用和取消应用修补程序:

class TestFoo(unittest.TestCase):
    def setUp(self):
        self.patch1 = mock.patch(...)
        self.patch1.start()

    def tearDown(self):
        self.patch1.stop()

此处patch1在设置时启动,并在测试被拆除时再次停止。这就像上下文管理器一样,但却挂钩了测试边界。

您可以使用TestCase.addCleanup()注册tearDown作为清理功能,而不是使用patch.stop()

class TestFoo(unittest.TestCase):
    def setUp(self):
        patch1 = mock.patch(...)
        patch1.start()
        self.addCleanup(patch1.stop)

答案 1 :(得分:0)

您可以使用mock.patch.startmock.patch.stop。 (见patch methods: start and stop)。

例如:

class MyTest(TestCase):

    def setUp(self):
        self.patcher = mock.patch('...')
        self.MockClass = self.patcher.start()

    def tearDown(self):
        self.patcher.stop()

    def test_something(self):
        ....

答案 2 :(得分:-1)

适用于所有上下文管理器的最通用解决方案是:

import unittest

class TCase(unittest.TestCase):
    def setUp(self):
        self.cm = mock.path(...)
        self.cm.__enter__()

    def test1(self):
        ...

    def tearDown(self):
        self.cm.__exit__(None, None, None)