我应该如何测试模拟对象的方法

时间:2019-06-20 21:39:58

标签: python unit-testing python-unittest.mock

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

我想测试结构类库中的deploy_file方法调用了结构库中的“ 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,则在创建Connection对象时会收到与“主机”参数有关的错误。

我认为,当调用“ conn.put”时,它会创建一个全新的Mock对象,而当unittest运行时,我不会测试该对象。我只是不确定如何定义测试以实际测试放置请求。

我还是一个了解如何测试(以及如何测试)和不测试什么以及如何使用模拟等的新手。我完全同意这个想法。在我从事项目时发现错误和回归非常有帮助。

0 个答案:

没有答案