I am trying to write unit test for some of Python classes I have created. I have created a class for wrapping s3 functionalities, and in that class I'm initializing boto3 s3 client.
class S3_Client:
def __init__(self, bucket_name):
self.s3 = boto3.client("s3", aws_access_key_id=e_config["aws_access_key"], aws_secret_access_key=e_config["aws_secret_key"])
self.bucket_name = bucket_name
def fetch(self, key):
response = self.s3.get_object(Bucket=self.bucket_name, Key=key)
return self.__prepare_file_info(response, key) # return formatted response
I would like to test method fetch with mocked response from self.s3.get_object. This is my test class:
import unittest
from .aws_s3_service import S3_Client # class I want to test
import boto3
from botocore.stub import Stubber
class TestS3_Client(unittest.TestCase):
def setUp(self):
self.client = boto3.client('s3')
self.stubber = Stubber(self.client)
def test_fetch(self):
get_object_response = {...} # hardcoded response
self.stubber.add_response('get_object', get_object_response, {"Bucket": "test_bucket", "Key": "path/to/file/test_file.txt"})
with self.stubber:
client = S3_Client("test_bucket")
result = client.fetch("path/to/file/test_file.txt")
The stubber is not actually injected into S3_Client, a real call to S3 is made. How do I inject the stubber? Any help is appreciated, thanks.
You need to make S3_Client
accept a client object in a constructor argument. In this way in your tests you can create a client, stub it, then inject it to S3_Client
as a parameter.
If you don't like having to always create that client outside of the class, you can make it an optional argument, and create an instance in __init__
if none was passed:
class S3_Client:
def __init__(self, bucket_name, s3=None):
if s3 is None:
self.s3 = boto3.client("s3", aws_access_key_id=e_config["aws_access_key"], aws_secret_access_key=e_config["aws_secret_key"])
else:
self.s3 = s3
self.bucket_name = bucket_name
...
In the code of your test you would then say: client = S3_Client("test_bucket", self.client)
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.