2017-03-20 1 views
1

데코레이터 authorized()을 정의하는 파이썬 모듈 security.py이 있습니다.플라스크 요청에 패치하여 파이썬 패키지의 데코레이터에 대한 단위 테스트

데코레이터를 테스트하고 싶습니다. 데코레이터는 플라스크 요청 헤더를 수신합니다. 나는 내가 쓴 decorator.The 시험이 같은 STH하는 @patch 사용하여 플라스크 요청 헤더를 조롱 할

def authorized(): 
    def _authorized(wrapped_func): 
     def _wrap(*args, **kwargs): 
      if 'token' not in request.headers: 
       LOG.warning("warning") 
       abort(401) 
       return None 
      return wrapped_func(*args, **kwargs) 
     return _wrap 
    return _authorized 

: 데코레이터는 다음과 같이 s 번째입니다

@patch('security.request.headers', Mock(side_effect=lambda *args, **kwargs: MockHeaders({}))) 
def test_no_authorization_token_in_header(self): 
    @security.authorized() 
    def decorated_func(token='abc'): 
     return access_token 

    result = decorated_func() 
    self.assertEqual(result, None) 

class MockHeaders(object): 
    def __init__(self, json_data): 
     self.json_data=json_data 

하지만 난 항상 다음을 얻을 오류 :

name = 'request' 

def _lookup_req_object(name): 
    top = _request_ctx_stack.top 
    if top is None: 
     raise RuntimeError(_request_ctx_err_msg) 

     RuntimeError: Working outside of request context. 

     This typically means that you attempted to use functionality that needed 
     an active HTTP request. Consult the documentation on testing for 
     information about how to avoid this problem. 

어떻게해야합니까?

+0

@MartijnPieters 네 클래스가 이후에 권리 또한 메타 데이터 다른 장식이 제대로 전달되어 추가 할 수 있도록 functools.wraps()를 사용한다 패치로 꾸며진 방법 – yellowbowlmigration

+0

죄송합니다. Mea Culpa. –

답변

2

모의 전체 요청 오브젝트 컨텍스트 검색 트리거 방지하려면

@patch('security.request') 

를 거기로부터 모형을 구축 일 : Abort 예외 누락 토큰 결과 이후

@patch('security.request') 
def test_no_authorization_token_in_header(self, mock_request): 
    mock_request.headers= {} 

    @security.authorized() 
    def decorated_func(token='abc'): 
     return token 

    self.assertRaises(Abort): 
     result = decorated_func() 

제기되는 그것을 명시 적으로 테스트해야합니다. request.headers 속성은 아무데도 호출되지 않으므로 side_effect 또는 return_value 속성은 여기에 적용되지 않습니다.

나는 모두 MockHeaders을 무시했습니다. 귀하의 데코레이터가 json_data을 사용하지 않고 귀하의 구현에 __contains__ 메소드가 없기 때문에 in 테스트가 해당 테스트에서 작동하지 않습니다. 일반 사전은 현재 테스트중인 코드에 충분합니다.

사이드 노트 : authorized은 데코레이터 팩토리이지만 매개 변수를 사용하지 않습니다. 공장을 전혀 사용하지 않으면 더 명확 해집니다.

from functools import wraps 

def authorized(wrapped_func): 
    @wraps(wrapped_func) 
    def _wrap(*args, **kwargs): 
     if 'token' not in request.headers: 
      LOG.warning("warning") 
      abort(401) 
      return None 
     return wrapped_func(*args, **kwargs) 
    return _wrap 

다음 (그래서 호출) 직접 장식을 사용하지 :

@security.authorized 
def decorated_func(token='abc'): 
    return access_token 
관련 문제