[英]pytest - mock config[<section_name>] via configparser.ConfigParser() / config.read()
[英]How can i mock configparser.ConfigParser read method in python
我正在使用 python 并且是新手。 我正在尝试为我的 class 方法编写单元测试,我们使用 configparse 来获取位于特定路径的配置文件详细信息。
在进行单元测试时,它给我一个错误,如 KeyError for <configparser.ConfigParser object at 0x000001E8AEBC1F40>
configparser 的代码就像
algor_conf = configparser.ConfigParser()
self.algor_conf.read('./path')
self.algor_conf['DynamicProgramingParamaters']['wealth_state_total']
谁能帮我嘲笑这个
这里有一些适合您的解决方案。 随意选择最适合您需要的 6 个(名为test_mock1
到test_mock6
)。
源文件
import configparser
class MyClass:
def my_method(self):
self.algor_conf = configparser.ConfigParser()
self.algor_conf.read('./path')
return self.algor_conf['DynamicProgramingParamaters']['wealth_state_total']
test_src.py
import configparser
from unittest.mock import patch
import pytest
from src import MyClass
def custom_get_item(key):
if key == 'DynamicProgramingParamaters':
return {'wealth_state_total': 'Just a test 3!'}
else:
raise KeyError(str(key))
class CustomConfigParser1(configparser.ConfigParser):
def __getitem__(self, key):
if key == 'DynamicProgramingParamaters':
return {'wealth_state_total': 'Just a test 4!'}
else:
raise KeyError(str(key))
class CustomConfigParser2(configparser.ConfigParser):
def read(self, filenames, *args, **kwargs):
# Intercept the calls to configparser -> read and replace it to read from your test data
if './path' == filenames:
# Option 1: If you want to manually write the configuration here
self.read_string("[DynamicProgramingParamaters]\nwealth_state_total = Just a test 5!")
# Option 2: If you have a test configuration file
# super().read("./test_path")
else:
super().read(filenames, *args, **kwargs)
@pytest.fixture
def amend_read(mocker): # Requires https://pypi.org/project/pytest-mock/ but you can also change this to just use the builtin unittest.mock
original_func = configparser.ConfigParser.read
def updated_func(self, filenames, *args, **kwargs):
# Intercept the calls to configparser -> read and replace it to read from your test data
if './path' == filenames:
# Option 1: If you want to manually write the configuration here
self.read_string("[DynamicProgramingParamaters]\nwealth_state_total = Just a test 6!")
# Option 2: If you have a test configuration file
# original_func.read(self, "./test_path")
return
return original_func(self, filenames, *args, **kwargs)
mocker.patch('configparser.ConfigParser.read', new=updated_func)
@patch('configparser.ConfigParser')
def test_mock1(config_parser):
# If you just want to mock the configparser without doing anything to its processing results
obj = MyClass()
result = obj.my_method()
print(result)
@patch('configparser.ConfigParser.__getitem__', return_value={'wealth_state_total': 'Just a test 2!'})
def test_mock2(config_parser):
# Change the returned value of configparser['DynamicProgramingParamaters']['wealth_state_total']
obj = MyClass()
result = obj.my_method()
print(result)
@patch('configparser.ConfigParser.__getitem__', side_effect=custom_get_item)
def test_mock3(config_parser):
# Same as test_mock2 only that we instead used a function to write the return
obj = MyClass()
result = obj.my_method()
print(result)
@patch('configparser.ConfigParser', side_effect=CustomConfigParser1)
def test_mock4(config_parser):
# Same as test_mock3 only that we instead used a class to write the return
obj = MyClass()
result = obj.my_method()
print(result)
@patch('configparser.ConfigParser', side_effect=CustomConfigParser2)
def test_mock5(config_parser):
# If have a configuration file for your test data, use this.
obj = MyClass()
result = obj.my_method()
print(result)
def test_mock6(amend_read):
# Same as test_mock5 only that we instead used a function to write the return
obj = MyClass()
result = obj.my_method()
print(result)
Output
$ pytest -rP
test_mock.py ...... [100%]
============================================================================================ PASSES ============================================================================================
__________________________________________________________________________________________ test_mock1 __________________________________________________________________________________________
------------------------------------------------------------------------------------- Captured stdout call -------------------------------------------------------------------------------------
<MagicMock name='ConfigParser().__getitem__().__getitem__()' id='140151691208160'>
__________________________________________________________________________________________ test_mock2 __________________________________________________________________________________________
------------------------------------------------------------------------------------- Captured stdout call -------------------------------------------------------------------------------------
Just a test 2!
__________________________________________________________________________________________ test_mock3 __________________________________________________________________________________________
------------------------------------------------------------------------------------- Captured stdout call -------------------------------------------------------------------------------------
Just a test 3!
__________________________________________________________________________________________ test_mock4 __________________________________________________________________________________________
------------------------------------------------------------------------------------- Captured stdout call -------------------------------------------------------------------------------------
Just a test 4!
__________________________________________________________________________________________ test_mock5 __________________________________________________________________________________________
------------------------------------------------------------------------------------- Captured stdout call -------------------------------------------------------------------------------------
Just a test 5!
__________________________________________________________________________________________ test_mock6 __________________________________________________________________________________________
------------------------------------------------------------------------------------- Captured stdout call -------------------------------------------------------------------------------------
Just a test 6!
====================================================================================== 6 passed in 0.03s =======================================================================================
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.