如何在python中模拟configparser.configparser读取方法

2024-09-30 16:42:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用python,而且对它还不熟悉。我正在尝试为我的类方法编写单元测试,其中我们使用configparse获取位于特定路径的配置文件详细信息

在进行单元测试时,它会给我一个错误作为<;位于0x000001E8AEBC1F40处的configparser.configparser对象>

snapshot of error

configparser的代码如下

 algor_conf = configparser.ConfigParser()
 self.algor_conf.read('./path')
 self.algor_conf['DynamicProgramingParamaters']['wealth_state_total']

有人能帮我嘲笑一下吗


Tags: 对象方法代码ltgtself路径conf
1条回答
网友
1楼 · 发布于 2024-09-30 16:42:16

这里有一些解决方案。您可以自由选择最适合您需要的6个选项(命名为test_mock1test_mock6

src.py

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\u 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)

输出

$ 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 =======================================================================================

相关问题 更多 >