【问题标题】:Python Pytest mocking three functionsPython Pytest 模拟三个函数
【发布时间】:2021-01-14 23:43:19
【问题描述】:

所以我对嘲笑很陌生。我想我需要模拟两个函数。

被测函数

def get_text_from_pdf(next_pdfs_path):
    # TODO test this function
    """
    pulls all text from a PDF document and returns as a string.
            Parameters:
                    next_pdfs_path (str): file path use r"" around path.
            Returns:
                    text (str): string of text
    """
    if os.path.isfile(next_pdfs_path):      # check file is a real file/filepath
        try:
            text = ''
            with fitz.open(next_pdfs_path) as doc:      # using PyMuPDF
                for page in doc:
                    text += page.getText()
            return text
        except (RuntimeError, IOError):
            pass
    pass

测试代码先试试

from unittest import mock

@mock.patch("content_production.fitz.open", return_value='fake_file.csv', autospec=True)
def test_get_text_from_pdf(mock_fitz_open):
    assert cp.get_text_from_pdf('fake_file.csv') == 'fake_file.csv'

错误

E       AssertionError: assert None == 'fake_file.csv'
E        +  where None = <function get_text_from_pdf at 0x00000245EDF8CAF0>('fake_file.csv')
E        +    where <function get_text_from_pdf at 0x00000245EDF8CAF0> = cp.get_text_from_pdf

我是否需要同时模拟 fitz.openos.path.isfile?如果可以,怎么办?

编辑

根据 njriasan 的反馈,我已经尝试过了

@mock.patch("content_production.os.path.isfile", return_value=True, autospec=True)
@mock.patch("content_production.fitz.Page.getText")
@mock.patch("content_production.fitz.open")
def test_get_text_from_pdf(mock_fitz_open, mock_path_isfile, mock_gettext):
    mock_fitz_open.return_value.__enter__.return_value = 'test'
    assert cp.get_text_from_pdf('test') == 'test'

但现在出现此错误。

>                       text += page.getText()
E                       AttributeError: 'str' object has no attribute 'getText'

【问题讨论】:

    标签: python-3.x unit-testing mocking pytest


    【解决方案1】:

    我认为你正在做的事情有几个问题。我看到的第一个问题是我认为你在嘲笑错误的功能。通过嘲笑 fitz.open(next_pdfs_path) 你仍然期待:

    for page in doc:
        text += page.getText()
    

    正确执行。我建议您将整个语句和文本结果更新包装在一个辅助函数中,然后对其进行模拟。如果您的系统上实际上不存在文件路径,那么您还需要模拟os.path.isfile。我相信可以通过添加第二个装饰器来完成(我认为没有任何限制)。

    【讨论】:

    • 我不能只模拟所有三个函数吗? isfile()open()gettext() 并跳过辅助函数还是不可能?
    • 你可以模拟所有三个,这很好。您需要确保 open 返回该行的可迭代对象。澄清一下,您需要所有非模拟代码,在这种情况下:python for page in doc: 才能正确执行唯一可能出现的额外问题是您需要模拟导入位置。因此,如果您在 example.py 中执行from module import func 的操作,则需要确保模拟 example.func,而不是 module.func。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2019-11-07
    • 1970-01-01
    • 1970-01-01
    • 2018-12-21
    • 1970-01-01
    相关资源
    最近更新 更多