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

时间:2015-04-07 10:58:30

标签: python mocking

假设我有以下代码:

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

   def method(self)
       key = self.bucket.new_key()
       key.set_contents()   

如何测试methodnew_keyset_content的模拟调用?我从以下方式开始

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

2 个答案:

答案 0 :(得分:2)

Bruno的答案是一个很好的提示,但是从你的评论中可以清楚地知道你正在使用遗留代码。

我不是boto专家,但如果您修补整个S3Connection而不是get_bucket()方法,我认为会更好。

现在你必须修补S3Connection factory (构造函数),之后你的模拟return_value将是我们要求get_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

答案 1 :(得分:0)

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

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

或者如果您更喜欢传递连接类(或任何可调用的):

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

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

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

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