【问题标题】:Stubbing vs Mocking in PythonPython 中的 Stubbing 与 Mocking
【发布时间】:2014-08-01 05:43:02
【问题描述】:

我想模拟或存根一个函数进行测试。不确定我的术语是否正确,如果我错了,请纠正我,但我理解模拟是使用类似于unittest.mock 的模拟库来创建一个假对象,并且期望它将接收哪些参数以及它将接收什么参数将返回,等等。这对我来说似乎有点矫枉过正,因为我想要的只是模拟/存根方法要做的就是返回一个设定值。

我认为存根只是“在没有库的情况下进行模拟”,就像this question 的答案一样。据我所知,这正是我想要的。它既轻巧又简单,您不必为简单的情况考虑所有模拟选项。

我的问题是,这样做安全吗? 上面的问题似乎是覆盖了方法的内存表示,而且它看起来并不正确。这被python社区接受了吗?还是鼓励一直使用适当的模拟库?

编辑如果您没有按照链接的答案所述重新分配 finally 块中的方法,会发生什么样的可怕事情?

【问题讨论】:

  • 要检查您的测试是否安全,请编写另一个测试来测试您的模拟。没有什么比元测试更重要的了!
  • 实际上,您所描述的(返回设定值的对象)正是内置模拟库所做的,从您链接到的文档页面可以看到。
  • 模拟和存根之间普遍接受的主要区别是存根返回测试需要通过的数据,并且永远不会导致测试失败。模拟用于验证对不同组件之间交互的期望。模拟和存根都可以在没有库的情况下完成。

标签: python unit-testing mocking stub


【解决方案1】:

我想自己存根该方法的主要原因是这样我就不必担心模拟并进行设置。但是我发现this blog post 显示了使用带有注释的mock 库的绝佳方法,这比手动创建Mock 的实例要容易得多。摘录如下:

rm.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)

rmtest.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):

    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False

        rm("any path")

        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")

        # make the file 'exist'
        mock_path.isfile.return_value = True

        rm("any path")

        mock_os.remove.assert_called_with("any path")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    • 1970-01-01
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    相关资源
    最近更新 更多