簡體   English   中英

pytest - 模擬配置[<section_name> ] 通過 configparser.ConfigParser() / config.read()

[英]pytest - mock config[<section_name>] via configparser.ConfigParser() / config.read()

目標:我想測試我們的 Web 服務連接包裝器,例如 GitLab、SFTP、MySQL。 我被困在以下部分:

config = configparser.ConfigParser()
config.read(r"C:\git\config.ini")

我如何模擬/修補/MagicMock 以便config[<section_name>]返回 test_gitlab.py 中為給定鍵定義的值。 由於我們在各種 .py 文件中收到了上述結構的各種調用,如果可能的話,我希望不要更改實際的config.read(r"C:\\git\\config.ini")調用。

看似有前途但失敗的方法:

  • mock configparser.ConfigParser.read.return_value = config_dict --> 這不會改變變量配置,而是返回(最佳情況)沒有保存或中斷運行的字典
  • 通過config.add_section('GITLAB_TEST'), config.set('GITLAB_TEST', 'tokken', 'test_token')在 test_pytest.py 中添加 'GITLAB_TEST' 部分 --> config 及其定義的部分在 gitlab.py 中被覆蓋為config = configparser.ConfigParser()
    # ./module/io/gitlab.py
    import configparser
    import os
    import sys
    import gitlab
    
    class GitlabApi:
        def __init__(self, client=None):
            if sys.platform == "win32":
                config = configparser.ConfigParser()
                config.read(r"C:\git\config.ini")
                self.token = config["GITLAB_{}".format(client)]["token"]
    
        def return_client(self):
            self.api = gitlab.Gitlab(
                "https://gitlab.company_name.com", 
                private_token=self.token
            )
            self.api.auth()
            return self.api
    
    
    # ./tests/test_gitlab.py
    import pytest
    from unittest.mock import MagicMock
    from unittest.mock import Mock
    from ane.io import gitlab
    
    def test_return_client_win32():
        gitlab.sys = Mock(platform="win32")
        gitlab.gitlab.Gitlab = MagicMock()
    
        test_client, expected_private_token, expected_url = "test", "test_token", "test_url"
        config_dict = {
            "GITLAB_TEST": {"token": "test_token"},
            "GITLAB_SCRIPTS": {"token": "script_token"},
        }
    
    
        # following does not work
        gitlab.configparser.ConfigParser = MagicMock()
        gitlab.configparser.ConfigParser.return_value.read.return_value = config_dict
    
    
        gitlab.GitlabApi(client=test_client)  # mocked object
        gitlab.gitlab.Gitlab.assert_called_once_with(
            expected_url, private_token=expected_private_token
        )

一些沒有為我解決問題的 stackoverflows,但可能對其他人有幫助:

蟒蛇 3.7

我對上述問題的解決方案:模擬 config.read() 調用的內置 open()。 返回的fake_config_file基本上是以字節為單位的文件。

def test_return_client_win32():
    gitlab.sys = Mock(platform="win32")
    gitlab.gitlab.Gitlab = MagicMock()

    test_client = 'client'
    expected_private_token = 'expected_private_token'
    expected_url = "https://gitlab.company.name"
    fake_config_file = TextIOWrapper(
        BytesIO(
            b"[GITLAB_TEST]\ntoken: test_token\n"
            b"[GITLAB_SCRIPTS]\ntoken: script_token"
        )
    )

    gitlab.configparser.open = MagicMock(return_value=fake_config_file)
    gitlab.GitlabApi(client=test_client)
    gitlab.gitlab.Gitlab.assert_called_once_with(
        expected_url, private_token=expected_private_token
    )

一般來說,我目前建議的方法是:尋找字符串類型的返回值。 深入研究方法,直到找到返回字符串或類似內容的方法。 這是你嘲笑的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM