繁体   English   中英

我如何模拟 python 中的 configparser.ConfigParser 读取方法

[英]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_mock1test_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM