【问题标题】:Mocking Excel file content in Python with Openpyxl使用 Openpyxl 在 Python 中模拟 Excel 文件内容
【发布时间】:2022-01-26 08:11:05
【问题描述】:

下面是一个更复杂的问题的简化,这里我需要验证 Excel 文件的内容。我想为我需要的功能编写单元测试,但理想情况下我想模拟这些测试,这样我就不必有可用的示例 Excel 表。

以下功能起作用:

functions_to_test.py:

import openpyxl

def read_excel_file_contents(filename: str, sheetname: str, cell: str) -> str:
    wb = openpyxl.load_workbook(filename, read_only=True)
    ws = wb[sheetname]
    return ws[cell].value

test.py

import unittest
from unittest.mock import MagicMock, patch

import functions_to_test


class FunctionsToTest(unittest.TestCase):
    
    @patch('functions_to_test.openpyxl')
    def test_read_mocked_excel_file(self, openpyxl_mock):
        wb = openpyxl_mock.workbook()
        ws = openpyxl_mock.worksheet()

        openpyxl_mock.load_workbook = MagicMock(return_value=wb)
        wb.get_sheet_by_name = MagicMock(return_value=ws)
        ws["A1"].value = "Some content"       
        self.assertEqual(
            functions_to_test.read_excel_file_contents("a mocked excel file", sheetname="somesheet", cell="A1"), 
            "Some content"
            )


if __name__ == "__main__":
    unittest.main()

输出:

======================================================================
FAIL: test_read_mocked_excel_file (__main__.FunctionsToTest)
Assert the correct contents of reading a mocked Excel file
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\markh\AppData\Local\Programs\Python\Python39\lib\unittest\mock.py", line 1337, in patched
    return func(*newargs, **newkeywargs)
  File "c:\Users\markh\Python\Testing\test.py", line 18, in test_read_mocked_excel_file
    self.assertEqual(
AssertionError: <MagicMock name='openpyxl.workbook().__ge[45 chars]200'> != 'Some content'

----------------------------------------------------------------------
Ran 1 test in 0.003s

我相信我必须为此使用 MagicMock(),但似乎无法弄清楚到底如何。 我看过Mocking Method Calls In Python,但与那里给出的答案相比,我的情况似乎更进一步。

【问题讨论】:

    标签: python unit-testing mocking openpyxl python-3.9


    【解决方案1】:

    考虑对test.py 进行以下修改(请检查一切是否合理):

    基本上,我的想法是确保新初始化的工作簿wb 有一个使用.create_sheet 标记为somesheet 的工作表。然后,将ws 设置为该工作表,最后设置单元格A1 的值。

    test.py

    import unittest
    from unittest.mock import MagicMock, patch
    
    import functions_to_test
    
    
    class FunctionsToTest(unittest.TestCase):
    
        @patch('functions_to_test.openpyxl')
        def test_read_mocked_excel_file(self, openpyxl_mock):
            wb = openpyxl_mock.workbook()
            wb.create_sheet("somesheet")
            ws = wb["somesheet"]
            ws["A1"].value = "Some content"
    
            openpyxl_mock.load_workbook = MagicMock(return_value=wb)
            self.assertEqual(
                functions_to_test.read_excel_file_contents(
                    "a mocked excel file",
                    sheetname="somesheet",
                    cell="A1"
                ),
                "Some content"
            )
    
    
    if __name__ == "__main__":
        unittest.main()
    
    

    【讨论】:

    • 非常感谢您花时间回答!我正在尝试测试您的建议,如果我将 read_excel_file 的返回值从 return ws[cell].value 更改为 return ws['A2'].value,我预计测试会失败(或者类似地,如果我在 ws["A1"] 下添加 ws["A2"].value= "Some more content"。 value = "Some content" 到测试并调用functions_to_tet.read_excel_file_contents(..., cell="A2"),它仍然在寻找单元格A1,所以它似乎没有在测试中寻找正确的单元格。任何建议?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 1970-01-01
    相关资源
    最近更新 更多