当您测试一些私有方法时,我已将它们添加到我称为 s3.py 的模块中,其中包含您的代码:
import json
def _connect_to_s3():
raise
def _get_customer_bucket(conn):
raise
def _get_customer_key(bucket, customer):
raise
def build_customer_registry_dict(cust):
raise
def write_to_customer_registry(customer):
# establish a connection with S3
conn = _connect_to_s3()
# build customer registry dict and convert it to json
customer_registry_dict = json.dumps(build_customer_registry_dict(customer))
# attempt to access requested bucket
bucket = _get_customer_bucket(conn)
s3_key = _get_customer_key(bucket, customer)
s3_key.set_metadata('Content-Type', 'application/json')
s3_key.set_contents_from_string(customer_registry_dict)
return s3_key
接下来,在另一个模块 test_s3.py 中,我测试了您的代码,并考虑到对于单元测试,所有与第三方的交互,例如对 s3 的网络调用都应该修补:
from unittest.mock import MagicMock, Mock, patch
from s3 import write_to_customer_registry
import json
@patch('json.dumps', return_value={})
@patch('s3._get_customer_key')
@patch('s3.build_customer_registry_dict')
@patch('s3._get_customer_bucket')
@patch('s3._connect_to_s3')
def test_write_to_customer_registry(connect_mock, get_bucket_mock, build_customer_registry_dict_mock, get_customer_key_mock, json_mock):
customer = MagicMock()
connect_mock.return_value = 'connection'
get_bucket_mock.return_value = 'bucket'
get_customer_key_mock.return_value = MagicMock()
write_to_customer_registry(customer)
assert connect_mock.call_count == 1
assert get_bucket_mock.call_count == 1
assert get_customer_key_mock.call_count == 1
get_bucket_mock.assert_called_with('connection')
get_customer_key_mock.assert_called_with('bucket', customer)
get_customer_key_mock.return_value.set_metadata.assert_called_with('Content-Type', 'application/json')
get_customer_key_mock.return_value.set_contents_from_string.assert_called_with({})
正如您从测试中看到的那样,我没有测试set_contents_from_string 正在做应该做的事情(因为应该已经被 boto 库测试过),但是它是用正确的参数调用的。
如果您仍然怀疑 boto 库没有正确测试此类调用,您可以随时在 boto Github 或 boto3 Github 中自行检查
您可以测试的其他一点是您正在正确处理代码中的不同异常和边缘情况。
最后,您可以在docs 中找到有关修补和模拟的更多信息。通常关于where to patch 的部分非常有用。
其他一些资源是这个 blog post 和 python mock gotchas 或者这个 blog post 我在 Stackoverflow 中回答了相关的 pytest、修补和模拟问题后写了自己(无耻的自我插件)。