使用相同的模拟在两个不同的文件中修补相同的模块

时间:2013-08-21 07:26:47

标签: python unit-testing mocking

我正在使用mock库来修补由两个文件导入的模块,这两个文件定义了一个类及其子类。类似的东西:

# ---- file module_to_patch.py -----
def foo():
    return 1

def faa():
    return 2

# ---- file base_class.py -----
import module_to_patch

class base_class(object):
    def __init__(self):
        self.x = module_to_patch.foo()

# ---- file sub_class.py -----
import module_to_patch

class sub_class(object):
    def __init__(self):
        super(sub_class, self).__init__()
        self.y = module_to_patch.faa()

据我了解(请参阅here),在我的测试中,我应修补base_class.module_to_patchsub_class.module_to_patch,例如:

# file test_sub_class.py:
from unittest import TestCase
from mock import patch

class TestSubClass(TestCase):

    def setUp(self):
        self.patcher_1 = patch('base_class.module_to_patch', autospec=True)
        self.mock_1 = self.patcher_1.start()
        self.patcher_2 = patch('sub_class.module_to_patch', autospec=True)
        self.mock_2 = self.patcher_2.start()

    def tearDown(self):
        patch.stopall()

问题:

  • 是否有更简单的方法来实现此功能?
  • 如果不是 - 两个补丁都修补同一个实体,我如何让两个补丁返回相同的Mock()对象?我只是将mock_1作为patcher_2对象传递给new吗?
  • 以上是处理这种情况的正确方法吗?

1 个答案:

答案 0 :(得分:0)

实现我认为您尝试做的最简单的方法是简单地模拟导入对象中的模块。如果你只是想模拟整个测试套件的模块:

# file test_sub_class.py:
from unittest import TestCase
from mock import Mock

import sub_class
import base_class
MODULE_MOCK = Mock()
sub_class.module_to_patch = MODULE_MOCK
base_class.module_to_patch = MODULE_MOCK

class TestSubClass(TestCase):

    def test_sub_class_init(self):
        self.base_class = base_class.base_class()
        self.assertTrue(MODULE_MOCK.foo.called)

        self.sub_class = sub_class.sub_class()
        self.assertTrue(MODULE_MOCK.faa.called)

如果您只想模拟一个测试,可以使用patch.object作为装饰器并为其提供您希望patch.object使用的Mock对象(MOCK_OBJECT):

# file test_sub_class.py:
from unittest import TestCase
from mock import Mock, patch

import sub_class
import base_class

MOCK_OBJECT = Mock()

class TestSubClass(TestCase):

    @patch.object(sub_class, 'module_to_patch', MOCK_OBJECT)
    @patch.object(base_class, 'module_to_patch', MOCK_OBJECT)
    def test_sub_class_init(self):
        self.base_class = base_class.base_class()
        self.assertTrue(MOCK_OBJECT.foo.called)
        self.sub_class = sub_class.sub_class()
        self.assertTrue(MOCK_OBJECT.faa.called)