Pytest mock pandas read_excel 里面的 Class 构造
Pytest mock pandas read_excel inside the Class Construction
我正在使用 Pytest 进行一些集成测试。我正在读取来自 class 构造函数的 excel sheet 输入。我不知道如何模拟 pandas 的 read_excel 函数。
我的实际代码,
import pandas as pd
class Sample:
def __init__(self, input_file_path):
self.df_input = pd.read_excel(
input_file_path, sheet_name="Input sheet", header=[0]
)
def calculation(self):
pass
def choose_template(self):
pass
sample_obj = Sample('./test.xlsx')
sample_obj.choose_template()
test_one.py,
@mock.patch.dict(os.environ, {"DB_CONNECTION_STRING": "Mock_Connection_String",
"DB_DATABASE": "Mock_Db",
"AZURE_STORAGE_CONNECTION_STRING": "Mock_Azure_connection_String",
},clear=True)
def test_choose_template_valid():
expected = "fizz"
sample_obj = Sample('./test.xlsx')
sample_obj.choose_template()
actual = "fizz"
assert actual == expected
我收到以下错误。我明白为什么会这样。但是我需要一个关于如何模拟 pd.read_excel
调用的解决方案。
=============================================================== short test summary info ================================================================
FAILED test_report.py::test_choose_template_valid - FileNotFoundError: [Errno 2] No such file or directory: './test.xlsx'
================================================================== 1 failed in 0.96s ===================================================================
您的主要问题是您的代码在导入模块时已经执行。在这种情况下,您不能在调用它之前模拟它。
在通常的 if __name__ == "__main__"
检查后调用该代码,或者更好的是,移入一个函数,并在检查后调用该函数:
class Sample:
...
def choose_sample_template(file_name):
sample_obj = Sample(file_name)
return sample_obj.choose_template()
if __name__ == "__main__":
choose_sample_template('./test.xlsx')
现在您可以在测试该功能时以通常的方式模拟 pd.read_excel
:
@mock.patch.dict(...)
@mock.patch("your_module.pd.read_excel")
def test_choose_template_valid(mocked_read):
mocked_read.return_value = ... # some df
expected = "fizz"
actual = choose_sample_template('./test.xlsx')
assert actual == expected
其中 your_module
是定义 Sample
的模块。
如果您在测试的调用中多次调用 pd.read_excel
,如评论中所述,您可以使用 side_effect
而不是 return_value
:
@mock.patch.dict(...)
@mock.patch("your_module.pd.read_excel")
def test_choose_template_valid(mocked_read):
mocked_read.side_effect = [
some_df,
second_df,
third_df
]
...
我正在使用 Pytest 进行一些集成测试。我正在读取来自 class 构造函数的 excel sheet 输入。我不知道如何模拟 pandas 的 read_excel 函数。 我的实际代码,
import pandas as pd
class Sample:
def __init__(self, input_file_path):
self.df_input = pd.read_excel(
input_file_path, sheet_name="Input sheet", header=[0]
)
def calculation(self):
pass
def choose_template(self):
pass
sample_obj = Sample('./test.xlsx')
sample_obj.choose_template()
test_one.py,
@mock.patch.dict(os.environ, {"DB_CONNECTION_STRING": "Mock_Connection_String",
"DB_DATABASE": "Mock_Db",
"AZURE_STORAGE_CONNECTION_STRING": "Mock_Azure_connection_String",
},clear=True)
def test_choose_template_valid():
expected = "fizz"
sample_obj = Sample('./test.xlsx')
sample_obj.choose_template()
actual = "fizz"
assert actual == expected
我收到以下错误。我明白为什么会这样。但是我需要一个关于如何模拟 pd.read_excel
调用的解决方案。
=============================================================== short test summary info ================================================================
FAILED test_report.py::test_choose_template_valid - FileNotFoundError: [Errno 2] No such file or directory: './test.xlsx'
================================================================== 1 failed in 0.96s ===================================================================
您的主要问题是您的代码在导入模块时已经执行。在这种情况下,您不能在调用它之前模拟它。
在通常的 if __name__ == "__main__"
检查后调用该代码,或者更好的是,移入一个函数,并在检查后调用该函数:
class Sample:
...
def choose_sample_template(file_name):
sample_obj = Sample(file_name)
return sample_obj.choose_template()
if __name__ == "__main__":
choose_sample_template('./test.xlsx')
现在您可以在测试该功能时以通常的方式模拟 pd.read_excel
:
@mock.patch.dict(...)
@mock.patch("your_module.pd.read_excel")
def test_choose_template_valid(mocked_read):
mocked_read.return_value = ... # some df
expected = "fizz"
actual = choose_sample_template('./test.xlsx')
assert actual == expected
其中 your_module
是定义 Sample
的模块。
如果您在测试的调用中多次调用 pd.read_excel
,如评论中所述,您可以使用 side_effect
而不是 return_value
:
@mock.patch.dict(...)
@mock.patch("your_module.pd.read_excel")
def test_choose_template_valid(mocked_read):
mocked_read.side_effect = [
some_df,
second_df,
third_df
]
...