如何在测试中为多个功能重用相同的模拟

时间:2018-08-01 16:13:06

标签: python pandas unit-testing mocking pytest

我有一个测试文件,在这里我为每个功能重复使用相同的模拟。

@mock.patch.object(...)
def xyz(mock_xyz):
    mock_xyz.side_effect = lambda x, y: None
    ....

@mock.patch.object(...)
def abc(mock_xyz):
    mock_xyz.side_effect = lambda x, y: None
    ....

@mock.patch.object(...)
def lmn(mock_xyz):
    mock_xyz.side_effect = lambda x, y: None
    ....
.
.
.

如何避免每次都定义模拟? PS:我在示例中只使用了一个模拟,但是在6种测试方法中使用了相同的四个模拟。

2 个答案:

答案 0 :(得分:0)

您可以在setUp()中对其进行定义,并使其成为您的TestCase类的成员:

class MyTest(unittest.TestCase):
    def setUp(self):
        self.mock_xyz = mock.patch.object(...)
        self.mock_xyz.side_effect = lambda x, y: None

    def xyz(self):
        with self.mock_xyz:
            # Do test stuff
        ....

答案 1 :(得分:0)

我遇到了同样的问题,不太喜欢每个模拟对象使用一个上下文管理器的外观,因为 6+ 嵌套语句变得有点愚蠢。此外,无法在 python 2.7 上运行(即使使用 unittest2),所以不确定它是否是 python 3 的专有功能。

无论如何,我想我会把我的解决方案留在这里,以防其他人像我一样来寻求解决这个问题的方法。我最终得到了这样的结果:

import unittest2
from mock import patch

@patch('package.module.something')
@patch('package.module.SomeClass.something_else')
class TestBase(unittest2.TestCase):

    def setup_mocks(self, mock_object):
        mock_name = mock_object._mock_name
        if mock_name == 'something':
            # do something stuff
            mock_object.side_effect = lambda: 'something'
        elif mock_name == 'something_else':
            # do something else
            mock_object.side_effect = lambda: 'something else

    def test_stuff(self, *mocks):
        for m in mocks:
            self.setup_mocks(m)

        # do test stuff

现在我可以根据需要添加任意数量的模拟,并且每次测试都会对它们进行修补。如果在不同的模块中有两件相同的事情可能会遇到问题,但它还没有发生,所以当我遇到它时我会越过那座桥;)