python - python 中的严格模拟

标签 python unit-testing mocking python-mock

在 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)

在受限方法上设置异常(exception)

另一种方法是在您不想被调用的方法上明确设置失败:

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 以将 strict 参数添加到 Mock 构造函数并发送一个拉取请求。它要么被接受,要么 mock 维护者将指出如何实现这一点。 :)

关于python - python 中的严格模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24630720/

相关文章:

mocking - 在 VS 2012 中放弃 Pex 和 Moles?

java - 为 servlet 编写 JUNIT?

javascript - sinon模拟不接听电话

python - JSON解码错误: Expecting value: line 1 column 1 (char 0)

python - Jupyter Notebook 中的 tqdm 重复打印新的进度条

Python单元测试,某些方法只运行一次

javascript - 返回 promise 的 Jasmine 测试函数

java - 如何在 Java 中测试不同的 "tables input"?

python - CSV 到 JSON,从列创建数组

python - 如何使用 pymupdf 减小修改后的 PDF 的大小