2016-12-08 4 views
1

I 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) 

내가 무조건 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) 

그러나 어설 션이 실패한 경우, 도움이나 지침을 주시면 감사하겠습니다. MyClass.get_file()get_bucket()를 호출하지 않는 그것은 문제처럼 나에게 보이는

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

답변

0

이다. 그렇기 때문에 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' 대신에 같은 import를 테스트 해 봅니다. 그것은 여전히 ​​이상하지만, 나는 시험에서 이상 함을 더 용납합니다. 그러나, 당신이 처음에 조롱하려고하는 것에 대해 생각하고 싶을 수도 있습니다. 샘플 코드를 실행하려고 시도했지만 AWS에 연결하려고했습니다. [당신의 솔기가 어디에 있는지] (http://clear-lines.com/blog/post/Seams-Mocks-and-Functions.aspx)에 대해 생각해보고, 모두 조롱 해보십시오. –

+0

예 테스트 후 테스트를 리팩터링하고 업데이트합니다 (+1 링크). –