2014-08-30 3 views
9

파이썬 클래스의 한 클래스 메서드가 특정 인수 집합을 가진 다른 클래스 메서드를 호출한다고 주장하고 싶습니다. 조롱 된 클래스 메소드가 "spec-ed"가되기를 원합니다. 그래서 잘못된 개수의 인수로 호출되는지를 감지합니다.unmocked 클래스에서 autospec으로 classmethod를 패치하는 방법은 무엇입니까?

patch.object(.., autospec=True, ..)을 사용하여 classmethod를 패치하면 classmethod가 NonCallableMagicMock으로 바뀌고 호출하려고 할 때 오류가 발생합니다.

from mock import patch 

class A(object): 

    @classmethod 
    def api_meth(cls): 
     return cls._internal_classmethod(1, 2, 3) 

    @classmethod 
    def _internal_classmethod(cls, n, m, o): 
     return sum(n, m, o) 

with patch.object(A, '_internal_classmethod') as p: 
    print(type(p).__name__) 

with patch.object(A, '_internal_classmethod', autospec=True) as p: 
    print(type(p).__name__) 

는 출력을 생성합니다

MagicMock 
NonCallableMagicMock 

클래스가 조롱되지 속한 때 나는 _internal_classmethod에 대한 사양 - 에드 모의을 얻을 수 있습니까?

답변

4

autospec 대신 spec을 사용하고 직접 설정하십시오.

with patch.object(A, '_internal_classmethod', spec=A._internal_classmethod) as p: 
    print(type(p).__name__) 

나에게 출력

MagicMock 

을 제공합니다.

+6

이것은 NonCallableMagicMock을 되 찾는 문제를 해결하지만 불행히도 조롱 된 클래스 메서드에서 호출 서명 불일치를 잡는 동작을 제공하지 않습니다. 이 동작은 메서드의 호출 서명을 변경하여 코드 자체가 손상 되었더라도 통과 한 조롱 된 테스트를 보호하기 때문에 중요합니다. 나는 내가 찾고있는 행동이 "부분적인 자동 보호"라고 의심하고 아마도 모의이 그런 종류의 것을 지원하지 않을 것이라고 생각한다. – scanny

6

이 문제를 해결할 수있는 뛰어난 버그 보고서 (google code linkpython bug tracker link)가 있습니다. 수정이 통합 될 때까지, 나를 위해 일한 다음을 시도해 볼 수 있습니다. [2.7에, 3.x]에서도 작동한다고 생각합니다.

def _patched_callable(obj): 
    "Monkeypatch to allow autospec'ed classmethods and staticmethods." 
    # See https://code.google.com/p/mock/issues/detail?id=241 and 
    # http://bugs.python.org/issue23078 for the relevant bugs this 
    # monkeypatch fixes 
    if isinstance(obj, type): 
     return True 
    if getattr(obj, '__call__', None) is not None: 
     return True 
    if (isinstance(obj, (staticmethod, classmethod)) 
     and mock._callable(obj.__func__)): 
     return True 
    return False 
_patched_callable._old_func = mock._callable 
mock._callable = _patched_callable 

monkeypatch 후에는 제대로 패치 정전기에와 클래스 방법을 일반적으로 mock.patch을 사용하고있다 할 수 있어야한다.