Как я должен проверить метод макета объекта - PullRequest
1 голос
/ 21 июня 2019

У меня вопрос о том, как смоделировать вложенный метод и проверить, как он вызывался. Я с трудом могу разобраться: https://docs.python.org/3/library/unittest.mock-examples.html#mocking-chained-calls.

Я бы хотел проверить, что метод "put" из библиотеки Fabric вызывается методом deploy_file в этом классе, и, возможно, какие значения ему присвоены. Это модуль, который собирает некоторую информацию из AWS и предоставляет метод для действий с данными.

import json
import os

from aws.secrets_manager import get_secret
from fabric import Connection


class Deploy:
    def __init__(self):
        self.secrets = None
        self.set_secrets()

    def set_secrets(self):
        secrets = get_secret()
        self.secrets = json.loads(secrets)

    def deploy_file(self, source_file):
        with Connection(host=os.environ.get('SSH_USERNAME'), user=os.environ.get("SSH_USERNAME")) as conn:
            destination_path = self.secrets["app_path"] + '/' + os.path.basename(source_file)
            conn.put(source_file, destination_path)

"get_secret" - это метод в другом модуле, который использует библиотеку boto3 для получения информации от AWS.

Вот тесты, над которыми я работаю:

from unittest.mock import patch
from fabric import Connection
from jobs.deploy import Deploy


def test_set_secrets_dict_from_expected_json_string():
    with patch('jobs.deploy.get_secret') as m_get_secret:
        m_get_secret.return_value = '{"app_path": "/var/www/html"}'
        deployment = Deploy()
        assert deployment.secrets['app_path'] == "/var/www/html"


def test_copy_app_file_calls_fabric_put():
    with patch('jobs.deploy.get_secret') as m_get_secret:
        m_get_secret.return_value = '{"app_path": "/var/www/html"}'
        deployment = Deploy()
        with patch('jobs.deploy.Connection', spec=Connection) as m_conn:
            local_file_path = "/tmp/foo"
            deployment.deploy_file(local_file_path)
            m_conn.put.assert_called_once()

, где второй тест приводит к «AssertionError: Ожидаемый 'put' был вызван один раз. Вызывается 0 раз."

первый тест просто отлично проверяет функцию «get_secret», чтобы проверить, что конструктор для «Deploy» устанавливает «Deploy.secrets» из поддельных данных AWS.

Во втором тесте get_secrets высмеивается, как и раньше, и я высмеиваю «Соединение» из библиотеки Fabric. Если я не проверяю Connection, я получаю сообщение об ошибке, связанное с параметром "host", когда создается объект Connection.

Я думаю, что когда вызывается «conn.put», это создает совершенно новый объект Mock, и я не тестирую этот объект, когда выполняется unittest. Я просто не знаю, как определить тест для проверки вызова.

Я также новичок в понимании того, что тестировать (и как), а что нет, а также как использовать макет и тому подобное. Я полностью увлечен этой идеей. Было очень полезно находить ошибки и регрессии, когда я работаю над проектами.

...