2016-12-08 8 views
1

私は、S3からファイルをダウンロードするのbotoを使用するクラスを持っている方法は、接続をinitiliaseするS3Connectionクラスを使用して、後で取得するためにget_keyメソッドを使用していますを主張しますファイル'。ここ は、コードブロックはのboto例外にモックside_effectを割り当て、呼び出し

import sys 

from boto.exception import S3ResponseError, S3DataError 
from boto.s3.connection import S3Connection 

class MyClass(object): 
    def __init__(self): 
     self.s3conn = S3Connection(
       AWS_ACCESS_KEY_ID, 
       AWS_SECRET_ACCESS_KEY, 
       host=HOST, 
       is_secure=True 
     ) 
     self.bucket = self.s3conn.get_bucket(BUCKET_NAME) 
    def get_file(self, key): 
     try: 
      return self.bucket.get_key(key) 
     except (S3ResponseError, S3DataError): 
      sys.exit(3) 

私はALO sys.exitメソッドをモックと主張することができるように、それが呼ばれた、get_bucketメソッドをモックし、それをS3ResponseErrorのside_effectを与えたいです。

ここで私はそれをやっています。

import unittest 
import mock 
from boto.exception import S3ResponseError, S3DataError 
from mymodule import MyClass 

class TestS3(unittest.TestCase): 
    def setUp(self): 
     self.key = 'sample/bubket/key.txt' 
     self.myclass = MyClass() 

    def test_my_method(self): 
     exit_method = (
      'mymodule.' 
      'sys.' 
      'exit' 
     ) 
     s3_get_bucket = (
      'mymodule.' 
      'S3Connection.' 
      'get_bucket' 
     ) 


     with mock.patch(s3_get_bucket) as mocked_bucket, \ 
      mock.patch(exit_method) as mocked_exit: 
       mocked_bucket.side_effect = S3ResponseError 
       self.myclass.get_file(self.key) 
       mocked_exit.assert_called_once_with(3) 

ただし、アサーションは失敗しています。ヘルプやガイダンスは高く評価されます。

AssertionError: Expected to be called once. Called 0 times. 

答えて

0

問題はMyClass.get_file()get_bucket()を呼び出さないということであるようにそれは私には見えます。だからあなたはsys.exit()への呼び出しを見ていないのです。モックget_key()またはget_bucket()に電話してください。

+0

my_moduleファイルに 'boto.s3.connection import Bucket#noqa'をインポートしてパッチを当てることで合格となりました。 この[回答](http://stackoverflow.com/questions/30677100/how-do-you-pass-exception-arguments-to-python-unittest-mock-side-effect)も私を助けました。私はモックside_effectを 'mocked_bucket.side_effect = S3ResponseError 'に割り当てました( 403、"禁止されています "、 ) ' クラス(**バケット**)をインポートする場合、それはパッチを簡単にするために直接使用されていませんが、良い練習ですか? –

+0

私は良い練習のようには聞こえません、@ギデオンマナ。 'my_module'の代わりに同じインポートをテストに移動してみてください。それはまだ変だけど、私はテストで奇妙なことにもっと寛容です。しかし、あなたが最初に嘲笑しようとしていることについて考えてみてください。サンプルコードを実行しようとすると、AWSに接続しようとしていました。あなたの縫い目がどこにあるかを考えてみてください(http://clear-lines.com/blog/post/Seams-Mocks-and-Functions.aspx)。そのすべてを嘲笑してください。 –

+0

はいテスト後にテストをリファクタリングして更新します。リンクに対して+1します。 –

関連する問題