Как мне сменить методы boto3, вызываемые из пользовательского метода собственного класса? - PullRequest
0 голосов
/ 19 октября 2019

У меня есть файл Python file/s3.py с пользовательским классом S3 (с заглавной буквы), который имеет метод get_list_of_objects(). В этом методе есть цепочечные методы boto3, которые называются self.bucket.objects.filter()

Как мне высмеивать эти методы boto3?

project_dir/file/s3.py

import boto3
import botocore
import pandas


class S3:
    def __init__(self, bucket_name="my_bucket_of_stuff"):
        self.s3_resource = boto3.resource("s3")
        self.bucket = self.s3_resource.Bucket(bucket_name)
        self.s3_client = boto3.client("s3")
        self._bucket_name = bucket_name

    def get_list_of_objects(self, key_prefix):
        key_list = []
        for object_summary in self.bucket.objects.filter(Prefix=key_prefix):  #mock this bucket.objects.filter
            key_list.append(object_summary.key)
        return key_list

Моя попытка до сих пор project_dir/tests/test.py

import unittest
import file.s3
from unittest.mock import patch
from file.s3 import S3


class TestS3Class(unittest.TestCase):
    """TestCase for storage/s3.py"""

    def setUp(self):
        """Creates an instance of the live S3 class for testing"""
        self.s3_test_client = S3()


    @patch('file.s3.S3.bucket')
    @patch('file.s3.S3.bucket.objects')
    @patch('file.s3.S3.bucket.objects.filter')
    def test_get_list_of_objects(self, mock_filter, mock_objects, mock_bucket):
        """Asserts retrieved dictionary of S3 objects is processed and returned as type list"""
        mock_bucket.return_value = None
        mock_objects.return_value = None
        mock_filter.return_value = {'key': 'value'}
        self.assertIsInstance(self.s3_test_client.get_list_of_objects(key_prefix='key'), list)

Что приводит к ошибке ModuleNotFoundError: No module named 'file.s3.S3'; 'file.s3' is not a package

Я, должно быть, испортил местоположение патча, но я не уверен, как.

1 Ответ

0 голосов
/ 19 октября 2019

Мне было легче издеваться над классом boto3.resource, чем пытаться смоделировать эти методы из моего пользовательского класса. Итак, рабочий код теста:

@patch('boto3.resource')
    def test_get_list_of_objects(self, mock_resource):
        """Asserts retrieved dictionary of S3 objects is processed and returned as type list"""
        mock_resource.Bucket.return_value = {'key': 'value'}

        self.assertIsInstance(self.s3_test_client.get_list_of_objects(key_prefix='key'), list)

Теперь я получаю предупреждение, но тест проходит успешно и не проходит. ResourceWarning: unclosed <ssl.SSLSocket....

...