编程语言
首页 > 编程语言> > 在python中严格模拟

在python中严格模拟

作者:互联网

python中有没有相当于严格的模拟?报告模拟方法的非故意调用的一些机制(本例中为action.step2()),就像在GoogleMock框架中一样.

class Action:
    def step1(self, arg):
        return False

    def step2(self, arg):
        return False

def algorithm(action):
    action.step1('111')
    action.step2('222')
    return True

class TestAlgorithm(unittest.TestCase):
    def test_algorithm(self):
        actionMock = mock.create_autospec(Action)
        self.assertTrue(algorithm(actionMock))
        actionMock.step1.assert_called_once_with('111')

解决方法:

看起来它不是开箱即用的.但是,至少有两种方法可以实现相同的结果.

传递允许的成员列表

根据模拟文档

spec: This can be either a list of strings or an existing object (a class or instance) that acts as the specification for the mock object. If you pass in an object then a list of strings is formed by calling dir on the object (excluding unsupported magic attributes and methods). Accessing any attribute not in this list will raise an AttributeError.

因此,为了使您的测试示例失败,只需更换

actionMock = mock.create_autospec(Action)

actionMock = mock.Mock(spec=['step1'])

与将类或实例作为spec参数传递相比,这种方法有一些缺点,因为您必须传递所有允许的方法,而不是设置它们的期望,有效地将它们注册两次.此外,如果您需要限制方法的子集,则必须传递除这些方法之外的所有方法的列表.这可以通过以下方式实现:

all_members = dir(Action)  # according to docs this is what's happening behind the scenes
all_members.remove('step2')  # remove all unwanted methods 
actionMock = mock.Mock(spec=all_members)

设置受限方法的例外

替代方法是在您不希望被调用的方法上明确地设置失败:

def test_algorithm(self):
    actionMock = mock.create_autospec(Action)
    actionMock.step2.side_effect = AttributeError("Called step2") # <<< like this
    self.assertTrue(algorithm(actionMock))
    actionMock.step1.assert_called_once_with('111')

这也有一些限制:你必须设置错误和期望.

作为最后一点,这个问题的一个根本解决方案是修补mock以向Mock构造函数添加strict参数并发送拉取请求.它要么被接受,要么模拟维护者会指出如何实现这一点.

标签:python,unit-testing,mocking,python-mock
来源: https://codeday.me/bug/20190624/1278130.html