[英]How to mock a dependency's response when unit-testing in Python
I am trying to write unit test for some of Python classes I have created.我正在尝试为我创建的一些 Python 类编写单元测试。 I have created a class for wrapping s3 functionalities, and in that class I'm initializing boto3 s3 client.
我创建了一个用于包装 s3 功能的类,在该类中我正在初始化 boto3 s3 客户端。
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.我想使用来自 self.s3.get_object 的模拟响应来测试方法 fetch。 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.存根实际上并没有注入到 S3_Client 中,而是对 S3 进行了真正的调用。 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.您需要让
S3_Client
在构造函数参数中接受客户端对象。 In this way in your tests you can create a client, stub it, then inject it to S3_Client
as a parameter.通过这种方式,您可以在测试中创建一个客户端,存根它,然后将其作为参数注入
S3_Client
。
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:如果您不想总是在类之外创建该客户端,则可以将其设为可选参数,如果没有传递,则在
__init__
创建一个实例:
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)
.在你的测试代码中,你会说:
client = S3_Client("test_bucket", self.client)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.