在Python中模拟全局/模块级变量

时间:2019-09-17 19:17:44

标签: python-3.x mocking python-unittest

我有一个看起来像这样的模块:

import psycopg2

client = vault_client(vault_url, vault_certs_path, credentials)
vault_data = client.read(vault_path)['data']


def do_thing
     connection = psycopg2.connect(
                dbname=vault_data['database'],
                host=vault_data['cluster_name'],
               ...
               )

如何测试此do_thing方法。我需要模拟vault_data和psycopy2的导入。我需要确保:

  1. psycopg2.connect方法接收正确的参数
  2. 我该如何模拟vault_client方法以返回一个模拟,然后在该模拟上调用read方法时返回一个字典?

我有这个,但是真正的方法被称为:

    @mock.patch("sources.segment.handler")
    @mock.patch("sources.segment.handler.psycopg2")
    def test_attempts_to_connect_to_redshift(self, mock_psycopg2, mock_handler):
        mock_handler.vault_client.return_value = {
            "data": {
                "database": "some_database",
                "cluster_name": "some_cluster_name",
                "port": "some_port",
                "username": "some_username",
                "password": "some_password",
            }
        }
        do_thing()

        mock_psycopg2.connect.assert_called_with("some database")
        ...

1 个答案:

答案 0 :(得分:0)

这里的问题似乎是,在已经导入带有do_thing()的模块时模拟某些东西为时已晚。您可以尝试以下技巧:

import sys
from unittest.mock import MagicMock

psycopg2_mock = MagicMock()
sys.modules['psycopg2'] = psycopg2_mock
import module_with_do_thing
del sys.modules['psycopg2']

class TestSomething(unittest.TestCase):
    ...
    def test_attempts_to_connect_to_redshift(self):
        ...
        assert psycopg2_mock.has_required_properties

import module_with_do_thing行移到具有正确补丁的实际测试方法上也可能有效。