Сбой при запуске Pytest unittest с ошибкой атрибута

#python-3.x #pytest

#python-3.x #pytest

Вопрос:

Я создал нижеприведенную функцию, и она работает нормально, но я борюсь с созданием unittest для этой функции.

Вот моя функция:

  def put_config_file_on_device(device, config_backup=None):
    try:
        runn_config = config_backup
        runn_config_database = running_config_from_database(device)
        if runn_config:
            raw_config = runn_config
        else:
            raw_config = runn_config_database

        new_file, filename = tempfile.mkstemp()
        os.write(new_file, raw_config.encode('utf-8'))
        ssh = SSHClient()
        ssh.set_missing_host_key_policy(AutoAddPolicy())
        ssh.load_system_host_keys()
        handler = get_handler(device)
        passwd = handler._get_admin_passwords()[1][0]
        ssh.connect(device, username='root', password=get_cred('root'),  
                    look_for_keys=False)
        vendor = str(handler)
        if 'Juniper' in vendor:
            remote_path = f'/var/tmp/{device}.cfg'
        if 'Cisco' in vendor:
            remote_path = f'harddisk:/{device}.cfg'
        scp = SCPClient(ssh.get_transport())
        file_path = f'{filename}'
        scp.put(file_path, remote_path, recursive=False)
        scp.close()
        os.remove(filename)
        return True, f"File store successfully on the device {remote_path}"
    except Exception as err:
        return False, f"Failed to store config on Exception: {err}"
  

Я создал unittest ниже, но он не работает. Я получаю сообщение об ошибке при настройке UT.
я высмеял все зависимости, но не уверен, что не так с кодом. Я получаю ошибку атрибута дляSSHClient .

     @pytest.mark.parametrize('mock_config_backup', ['someconfigrn'])
    @patch("test.scripts.script.get_cred")
    @patch("test.scripts.script.os")
    @patch("test.scripts.script.SSHClient.")
    @patch("test.scripts.script.SCPClient")
    @patch("test.scripts.script.tempfile.mkstemp")
    @patch("test.scripts.script.get_device_handler")
    def test_put_config_file_on_device(mock_handler, mock_temp, mock_os, mock_ssh, mock_scp, mock_cred, mock_config_backup):
        conf = 'someconfigrn'
        mock_temp.return_value = new_file, filename
        mock.os.write(new_file, conf.encode('utf-8'))
        remote_path = '/var/tmp/devA.cfg'
        file_path = f'{filename}'
        mock_cred.return_value = 'xyz'
        ret = MagicMock() 
        ret.connect('devA', username='root', password='xyz', look_for_keys=False)
        mock_ssh.return_value = ret
        mock_scp.put = (file_path, remote_path)
        scp.close()
        mock.os.remove(filename)
        status, out = test.scripts.script.put_config_file_on_device(device, mock_config_backup)
        assert status and out == 'File store successfully on the device /var/tmp/devA.cfg'
  

получение ошибки ниже.

     =============================================================================================== FAILURES ===============================================================================================
____________________________________________________________________________ test_put_config_file_on_device[someconfigrn] ____________________________________________________________________________

args = (), keywargs = {'mock_config_backup': 'someconfigrn'}

    @wraps(func)
    def patched(*args, **keywargs):
        with self.decoration_helper(patched,
                                    args,
>                                   keywargs) as (newargs, newkeywargs):

/home/lib/python3.6/site-packages/mock/mock.py:1368: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/lib/python3.6/contextlib.py:81: in __enter__
    return next(self.gen)
/home/lib/python3.6/site-packages/mock/mock.py:1334: in decoration_helper
    arg = patching.__enter__()
/home/lib/python3.6/site-packages/mock/mock.py:1437: in __enter__
    original, local = self.get_original()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <mock.mock._patch object at 0x7f0e60450240>

    def get_original(self):
        target = self.getter()
        name = self.attribute
    
        original = DEFAULT
        local = False
    
        try:
            original = target.__dict__[name]
        except (AttributeError, KeyError):
            original = getattr(target, name, DEFAULT)
        else:
            local = True
    
        if name in _builtins and isinstance(target, ModuleType):
            self.create = True
    
        if not self.create and original is DEFAULT:
            raise AttributeError(
>               "%s does not have the attribute %r" % (target, name)
            )
E           AttributeError: <class 'paramiko.client.SSHClient'> does not have the attribute ''

/home/lib/python3.6/site-packages/mock/mock.py:1411: AttributeError
===================================================================================== 1 failed, 6 passed in 5.67s
  

Комментарии:

1. Пожалуйста, опубликуйте полную ошибку обратной трассировки.

2. @ewong, обновил вопрос с полным обратным отслеживанием. Спасибо

3. Я исправил ошибку атрибута, удалив дополнительный «период» после «@patch(«test.scripts.script. SSHClient.»)»

4. примечание: сделайте вашу функцию менее сложной, чтобы ее было легче тестировать. посмотрите, сколько вещей вам нужно исправить, чтобы заставить этот тест работать, это должно быть немедленным красным флагом