Python 在以下情况下,如何模拟方法调用?

Python 在以下情况下,如何模拟方法调用?,python,mocking,Python,Mocking,假设我有以下代码: class A def __init__(self) self.bucket = S3Connection().get_bucket() def method(self) key = self.bucket.new_key() key.set_contents() 如何测试方法对new\u key和set\u content的模拟调用?我从下面的方法开始 @patch('my_file.S3Connect

假设我有以下代码:

class A
   def __init__(self)
       self.bucket = S3Connection().get_bucket()

   def method(self)
       key = self.bucket.new_key()
       key.set_contents()   
如何测试
方法
new\u key
set\u content
的模拟调用?我从下面的方法开始

    @patch('my_file.S3Connection')
    test_method()
         a = A()

有人可能会说,最好的方法是避免在类中硬编码
S3Connection
,并将其作为参数传递,即:

class A(object):
    def __init__(self, connection):
        self.bucket = connection.get_buckets() 
或者,如果您更愿意传递连接类(或任何可调用的连接),请执行以下操作:

然后您可以将
S3Connection
设置为默认值:

class A(object):
    def __init__(self, connector=S3Connector):
        self.bucket = connector().get_buckets()

现在,您可以自由地传递任何“连接”类(或可调用),这使得模拟更容易。

Bruno的回答是一个很好的提示,但从您的评论可以清楚地看出,您正在使用遗留代码

我不是一个
boto
专家,但我想如果你修补整个
S3Connection
而不是它的
get\u bucket()
方法会更好

现在您必须修补
S3Connection
factory(构造函数),然后
return\u value
您的mock将成为我们请求
get\u bucket()
的对象

您的测试将成为:

@patch('my_file.S3Connection')
test_method(mock_s3connection)
     mock_bucket = mock_s3connection.return_value.get_bucket
     a = A()
     #Just for fun ... check if the patch works like expected
     assert a.bucket is mock_bucket
     a.method()
     #check method logic
     assert mock_bucket.new_key.set_contents.called

谢谢你的建议,但我没有选择改变代码
@patch('my_file.S3Connection')
test_method(mock_s3connection)
     mock_bucket = mock_s3connection.return_value.get_bucket
     a = A()
     #Just for fun ... check if the patch works like expected
     assert a.bucket is mock_bucket
     a.method()
     #check method logic
     assert mock_bucket.new_key.set_contents.called