【问题标题】:How to mock an imported module with pytest如何使用 pytest 模拟导入的模块
【发布时间】:2018-08-14 22:16:49
【问题描述】:

之前有人问过类似的问题,但我很难让它发挥作用。

如何模拟来自另一个文件的导入模块

我有一个文件:
b.py(命名与链接文档一致)

import cv2   # module 'a' in the linked docs

def get_video_frame(path):
    vidcap = cv2.VideoCapture(path)  # `a.SomeClass` in the linked docs
    vidcap.isOpened()
    ...

test_b.py

import b
import pytest # with pytest-mock installed

def test_get_frame(mocker):

    mock_vidcap = mocker.Mock()
    mock_vidcap.isOpened.side_effect = AssertionError

    mock_cv2 = mocker.patch('cv2.VideoCapture')
    mock_cv2.return_value = mock_vidcap

    b.get_video_frame('foo')    # Doesn't fail

    mock_vidcap.isOpened.assert_called()   # fails

我这样设置测试是因为在where to patch 中它指定如果

在这种情况下,我们要修补的类正在 a 模块上查找,因此我们必须修补 a.SomeClass:

@patch(‘a.SomeClass’)

我尝试了一些其他的修补组合,但它表现出相同的行为,这表明我没有成功修补模块。如果要应用补丁,b.get_video_frame('foo') 将由于side_effect 而失败; assert_called 失败,支持这个。

编辑以缩短我在get_video_frame 其余部分留下的问题的长度。不幸的是,我们留下的部分是关键部分。完整的功能是:

def get_video_frame(path):
    vidcap = cv2.VideoCapture(path)  # `a.SomeClass` in the linked docs
    is_open = vidcap.isOpened()
    while True:
        is_open, frame = vidcap.read()
        if is_open:
            yield frame
        else:
            break

【问题讨论】:

    标签: python mocking python-unittest


    【解决方案1】:

    这一行只是创建了一个生成器:

    b.get_video_frame('foo')
    

    永远不会到达is_open = vidcap.isOpened() 行,因为在测试函数中,生成器在开始时保持冻结状态,因此副作用永远不会出现。

    否则,您正在正确使用模拟程序和补丁。

    【讨论】:

      猜你喜欢
      • 2020-02-02
      • 2023-04-05
      • 2021-01-21
      • 2016-05-16
      • 1970-01-01
      • 2021-09-22
      相关资源
      最近更新 更多