How to mock a boto3 client object/call

匿名 (未验证) 提交于 2019-12-03 03:10:03

问题:

I'm trying to mock one particular boto3 function. My module, Cleanup, imports boto3. Cleanup also has a class, "cleaner". During init, cleaner creates an ec2 client:

self.ec2_client = boto3.client('ec2') 

I want to mock the ec2 client method: desribe_tags(), which python says is:

<bound method EC2.describe_tags of <botocore.client.EC2 object at 0x7fd98660add0>> 

the furthest I've gotten is importing botocore in my test file and trying:

mock.patch(Cleaner.botocore.client.EC2.describe_tags) 

which fails with:

AttributeError: 'module' object has no attribute 'EC2' 

How do I mock this method?

Cleanup looks like:

import boto3 class cleaner(object):     def __init__(self):         self.ec2_client = boto3.client('ec2') 

The ec2_client object is the one that has the desribe_tags() method. It's a botocore.client.EC2 object, but I never directly import botocore.

回答1:

I found a solution to this when trying to mock a different method for the S3 client

import botocore from mock import patch import boto3  orig = botocore.client.BaseClient._make_api_call  def mock_make_api_call(self, operation_name, kwarg):     if operation_name == 'DescribeTags':         # Your Operation here!         print(kwarg)     return orig(self, operation_name, kwarg)  with patch('botocore.client.BaseClient._make_api_call', new=mock_make_api_call):     client = boto3.client('ec2')     # Calling describe tags will perform your mocked operation e.g. print args     e = client.describe_tags() 

Hope it helps :)



回答2:

You should be mocking with respect to where you are testing. So, if you are testing your cleaner class (Which I suggest you use PEP8 standards here, and make it Cleaner), then you want to mock with respect to where you are testing. So, your patching should actually be something along the lines of:

class SomeTest(Unittest.TestCase):     @mock.patch('path.to.Cleaner.boto3.client', return_value=Mock())     def setUp(self, boto_client_mock):         self.cleaner_client = boto_client_mock.return_value      def your_test(self):         # call the method you are looking to test here          # simple test to check that the method you are looking to mock was called         self.cleaner_client.desribe_tags.assert_called_with() 

I suggest reading through the mocking documentation which has many examples to do what you are trying to do



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!