1

我有一个关于如何模拟嵌套方法并测试它被调用的问题。我很难理解:https ://docs.python.org/3/library/unittest.mock-examples.html#mocking-chained-calls 。

我想测试一下这个类中的 deploy_file 方法是否调用了 fabric 库中的“put”方法,也许给它赋予了什么值。这是从 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”的构造函数是否从假 AWS 数据中设置了“Deploy.secrets”。

在第二个测试中,get_secrets 像以前一样被模拟,我模拟了结构库中的“连接”。如果我不模拟 Connection,则会在创建 Connection 对象时收到与“host”参数相关的错误。

我认为当调用“conn.put”时,它会创建一个全新的 Mock 对象,并且在 unittest 运行时我没有测试该对象。我只是不确定如何定义测试来实际测试 put 的调用。

我也是了解要测试什么(以及如何测试)和不测试什么以及如何使用模拟等方面的新手。不过,我完全接受了这个想法。在我从事项目工作时,发现错误和回归非常有帮助。

4

0 回答 0