【问题标题】:How to mock imported library methods with unittest.mock in Python 3.5?如何在 Python 3.5 中使用 unittest.mock 模拟导入的库方法?
【发布时间】:2015-12-22 13:57:08
【问题描述】:

是否可以在 Python 3.5 中使用 unittest.mock 模拟导入模块的方法?

# file my_function.py
import os
my_function():
    # do something with os, e.g call os.listdir
    return os.listdir(os.getcwd())

# file test_my_function.py
test_my_function():
    os = MagickMock()
    os.listdir = MagickMock(side_effect=["a", "b"])
    self.assertEqual("a", my_function())

我希望 os.listdir 方法在第一次调用时返回指定的副作用“a”,但在 my_function 内部调用了未修补的 os.listdir。

【问题讨论】:

  • 是的,这是可能的,但您必须修补原始版本 - 参见例如docs.python.org/3/library/unittest.mock.html#the-patchers。通常,“如何” 问题不适合 SO。
  • @jonrsharpe 我已阅读元质量页面meta.stackexchange.com/questions/92074/… 并试图改进问题。但是,您能否详细说明这是否更符合质量标准和“如何在 Oracle 中进行 UPSERT(更新或插入表)?”甚至是那里列出的 good 标题的示例。这个问题很准确,与其他人相关,因为在修补和使用绑定到 MagicMock 之间显然有明显的区别,这对我阅读文档来说并不清楚。
  • @NoxMortem 现在你有一个明确的问题,我可以给你一个明确的答案。

标签: python unit-testing mocking


【解决方案1】:

unittest.mock 有两个主要职责:

  • 定义 Mock 对象:对象旨在跟随您的剧本并记录对模拟对象的每次访问
  • 修补引用并恢复原始状态

在您的示例中,您需要两个功能:通过模拟修补生产代码中使用的os.listdir 引用,您可以完全控制它的响应方式。 patch的使用方式有很多种,有的details to take care on how use itcavelets to know

在您的情况下,您需要测试my_function() 的行为,并且需要同时修补os.listdir()os.getcwd()。此外,您需要控制return_value(查看return_valueside_effect 差异的指定文档)。

我稍微重写了您的示例,使其更加完整和清晰:

my_function(nr=0):
    l = os.listdir(os.getcwd())
    l.sort()
    return l[nr]

@patch("os.getcwd")
@patch("os.listdir", return_value=["a","b"])
def test_my_function(mock_ld, mock_g): 
    self.assertEqual("a", my_function(0))
    mock_ld.assert_called_with(mock_g.return_value)
    self.assertEqual("a", my_function())
    self.assertEqual("b", my_function(1))
    with self.assertRaises(IndexError):
        my_function(3)

我使用装饰器语法是因为我认为它是一种更简洁的方式;此外,为了避免引入太多细节,我没有使用 autospecing 我认为这是一个非常好的做法。

最后一点:模拟是一个强大的工具,但使用它而不是滥用它,补丁只是你需要的补丁,仅此而已。

【讨论】:

  • 对它的工作方式/原因进行一些解释会很好。另请注意,最后两行似乎是对模拟按预期工作的测试,而不是测试中的实际函数,这似乎很奇怪。
  • 非常感谢您的回答,特别是提供两个关于详细信息和注意事项的额外链接以及放置关键字 autospec,这使得答案特别值得阅读!我现在知道如何使用 unittest.mock 解决问题并进一步研究更好的单元测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2016-01-26
  • 2017-10-03
  • 2015-08-23
相关资源
最近更新 更多