2015-04-07 47 views
2

假設我有以下代碼:如何在以下情況下模擬方法調用?

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

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

如何測試method我嘲諷調用new_keyset_content?我開始以下列方式

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

回答

2

布魯諾的答案是一個很好的提示,但從您的評論很明顯,你正在玩遺留的代碼。

我不是boto專家,但我認爲如果您修補整個S3Connection而不是其get_bucket()方法更好。

現在你必須修補S3Connection工廠(構造),之後你模仿的那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 
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() 

現在你可以自由地通過任何「連接」類(或可調用),這使得嘲笑更容易。

+0

感謝您的建議,但我沒有一個選項,更改代碼 – Cory

相關問題