2017-11-24 7 views
0

mock을 사용하여 함수를 단위 테스트하고 mock 객체 호출이 수행되었는지 테스트하려고한다. 아래의 코드에서 requests.post 객체는 조롱을 받고 requests.post.mock_calls 목록을 추적합니다. 다음 코드에서파이썬 mock.mock_calls가 @timeout 데코 레이팅 된 함수 내에서 만들어진 호출을 따르지 않는다.

코드 구조 :

import timeout_decorator 

def block_funds(trader_id, amounts): 

    @timeout_decorator.timeout(3, use_signals=False) 
    def _block_funds(block_url, amounts): 

     # requests.post.mock_calls empty here 
     result = requests.post(url=block_url, data=amounts) 
     # requests.post.mock_calls here has correct call recorded 

     return result.status_code 

    block_url = 'http:/someurl/somepath/{trader_id}'.format(trader_id=trader_id) 

    try: 

     # requests.post.mock_calls empty here 
     code = _block_funds(block_url, amounts) 
     # requests.post.mock_calls empty again here 

    except timeout_decorator.TimeoutError as ex: 
     logger.error('request failed') 
     code = 500 

    return code 
내가 mock 객체가 모든 통화의 기록을 유지 할 것으로 예상 code = _block_funds(block_url, amounts)에 대한 호출 후

하지만 mock_calls 목록은 즉시 비워됩니다 실행이 내부 시간 초과 래핑 함수 _block_funds()을 종료하면 실행됩니다. 모의 객체는 확실히 동일합니다. 모의 ID를 따라 객체가 변경되지 않았는지 확인합니다.

내가 뭘 잘못하고 있고 모의 전화를 잊어 버리지 않는 방법은 무엇입니까?

+0

당신이 테스트에서 비교하고 함수에 값을 테스트하는 일에 사용하는 모의 객체는 아마도 동일한 개체 수 없습니다 있습니다. 귀하의 질문에 귀하의 테스트 기능을 포함하십시오. – jordanm

+0

사실 나는 그 원인을 발견했습니다. 그것은'@ timeout' 데코레이터입니다. 아니요, 객체가 동일합니다. 모의 객체 ID를 따르고 있습니다.하지만 타임 아웃 데코레이터를 주석 처리하자마자 호출이 나타나고 테스트가 통과한다는 것을 알았습니다. 이제는 테스트에서 해결 방법을 찾아야합니다. – alexykot

답변

0

문제점을 발견했습니다. 시간 초과 데코레이터에 있으며 특히 use_signals=False 부분에 있습니다. timeout decorator documentation에 따르면, 제 시나리오 (멀티 스레드 웹 응용 프로그램)에서 시간 초과를 올바르게 사용하려면 신호를 사용하지 말고 멀티 프로세싱에 의존해야하며,이 경우에는 예기치 않은 문제가있는 모의가 있습니다. use_signals=False을 제거하거나 데코레이터를 완전히 제거하면 올바르게 작동합니다.

내 솔루션은 이제 데코레이터 자체를 조롱하고 문제를 피하는 것입니다. 직접 장식을 조롱

보정은 실용적으로 밝혀졌다. 대신에 나는 주위를 싸서 랩 조롱했습니다

def timeout_post(**kwargs): 
    @timeout_decorator.timeout(3, use_signals=False) 
    def _post(**kwargs): 
     return requests.post(**kwargs) 

    return _post(**kwargs)