admin管理员组

文章数量:1125090

I am stuck in mocking this code :

from unittest.mock import patch
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient

class MyConfig:

    def __init__(self, ftp_host=None, ftp_username=None, ftp_password=None, azure=False):
       if self._azure:
            key_vault_name = os.getenv("KEY_VAULT_NAME")
            kv_uri = f"https://{key_vault_name}.acme"
            credential = DefaultAzureCredential()
            client = SecretClient(vault_url=kv_uri, credential=credential)
            self._ftp_host = client.get_secret("ftp-host").value
            self._ftp_username = client.get_secret("ftp-username").value

       return

Then in my unittest

class TestMyConfig(unittest.TestCase):

    @patch('azure.keyvault.secrets.SecretClient', autospec=True)
    def setUp(self, mock):
        secret_client = mock.return_value
        secret_client.get_secret.side_effect = lambda x: {"ftp-host": "hostname", "ftp-user": "Donald Duck"}[x]
        self.azure = MyConfig(azure=True)
        return

But it still runs into trying to connect the vault on "acme" which of course results in error. Any advice ?

Edit 1

Patching all two objects like this results in the same error

class TestMyConfig(unittest.TestCase):

    @patch('azure.keyvault.secrets.SecretClient', autospec=True)
    @patch('azure.identity.DefaultAzureCredential', autospec=True)
    def setUp(self, mock, credential_mock):
        
        secret_client = credential_mock.return_value
        secret_client.get_secret.side_effect = lambda x: {"ftp-host": "hostname", "ftp-user": "Donald Duck"}[x]
        self.azure = MyConfig(azure=True)

        return

Edit 2

The import Order is :

from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient

# the setUp method is now :

    @patch('azure.keyvault.secrets.SecretClient', autospec=True)
    @patch('azure.identity.DefaultAzureCredential', autospec=True)
    def setUp(self, credential_mock, client_mock):

        secret_client = client_mock.return_value
        secret_client.get_secret.side_effect = lambda x: {"ftp-host": "hostname", "ftp-user": "Donald Duck"}[x]
        self.azure = MyConfig(azure=True)
 

If I change the path order to :

    @patch('azure.identity.DefaultAzureCredential', autospec=True)
    @patch('azure.keyvault.secrets.SecretClient', autospec=True)
    def setUp(self, credential_mock, client_mock):

It results in :

    raise AttributeError("Mock object has no attribute %r" % name)
    AttributeError: Mock object has no attribute 'get_secret'

本文标签: Mocking Python Azure Vault ObjectsStack Overflow