내 이해는 MagicMock 이 "매직 메서드"를 자동으로 수행하여 목록, 반복 등을 완벽하게 지원하는 Mock 의 상위 집합 이라는 것입니다. 그렇다면 일반 Mock이 존재 하는 이유는 무엇 입니까? 실제로 무시할 수 있는 제거 된 MagicMock 버전이 아닌가 ? 합니까 모의 클래스에서 사용할 수없는 어떠한 트릭도 알고 MagicMock를 ?
내 이해는 MagicMock 이 "매직 메서드"를 자동으로 수행하여 목록, 반복 등을 완벽하게 지원하는 Mock 의 상위 집합 이라는 것입니다. 그렇다면 일반 Mock이 존재 하는 이유는 무엇 입니까? 실제로 무시할 수 있는 제거 된 MagicMock 버전이 아닌가 ? 합니까 모의 클래스에서 사용할 수없는 어떠한 트릭도 알고 MagicMock를 ?
답변:
Mock의 작가 인 Michael Foord 는 Pycon 2011 (31:00)에서 매우 비슷한 질문을했습니다 .
Q : 왜 MagicMock이 기본 모의 객체로 기능을 접는 대신 별도의 것을 만들었습니까?
A : 하나의 합리적인 대답은 MagicMock이 작동하는 방식은 새로운 Mocks를 생성하고 설정하여 이러한 모든 프로토콜 방법을 사전 구성한다는 것입니다. 메소드는 많은 모의를 만들고 프로토콜 메소드에 설정하면 무한 재귀를 얻습니다 ...
컨테이너 객체로 모의 객체에 오류가 있기를 원한다면 어떻게해야합니까? 모든 모의가 자동으로 모든 프로토콜 방법을 가지고 있다면 그렇게하기가 훨씬 더 어려워집니다. 또한 MagicMock 은이 사전 구성 중 일부를 수행하여 적절하지 않은 반환 값을 설정하므로 모든 것이 사전 구성되어 사용 가능한 편리한 편의를 갖는 것이 더 좋을 것이라고 생각했지만 일반적인 모의를 취할 수도 있습니다 객체를 선택하고 존재하는 마법 방법을 구성하십시오 ...
간단한 답변은 : 원하는 동작이라면 어디에서나 MagicMock을 사용하십시오.
Mock을 사용하면 마술 방법을 조롱 할 수 있지만 정의해야합니다. MagicMock에는 "대부분의 매직 메소드의 기본 구현"이 있습니다. .
마법 방법을 테스트 할 필요가 없다면 Mock이 적합하며 테스트에 많은 외적인 것들을 가져 오지 않습니다. 많은 마법 방법을 테스트해야하는 경우 MagicMock이 시간을 절약 해줍니다.
로 시작 MagicMock
하는의 하위 클래스입니다 Mock
.
class MagicMock(MagicMixin, Mock)
결과적으로 MagicMock은 Mock이 제공하는 모든 것을 제공합니다. Mock을 제거 된 MagicMock 버전으로 생각하기보다는 MagicMock을 확장 된 Mock 버전으로 생각하십시오. Mock이 존재하는 이유와 Mock이 MagicMock에서 무엇을 제공하는지에 대한 질문을 해결해야합니다.
둘째, MagicMock은 많은 / 대부분의 마법 메소드의 기본 구현을 제공하지만 Mock은 그렇지 않습니다. 제공된 마술 방법에 대한 자세한 내용 은 여기 를 참조 하십시오 .
제공된 마술 방법의 몇 가지 예 :
>>> int(Mock())
TypeError: int() argument must be a string or a number, not 'Mock'
>>> int(MagicMock())
1
>>> len(Mock())
TypeError: object of type 'Mock' has no len()
>>> len(MagicMock())
0
그리고 이것들은 직관적이지 않을 수도 있습니다 (적어도 직관적이지 않습니다).
>>> with MagicMock():
... print 'hello world'
...
hello world
>>> MagicMock()[1]
<MagicMock name='mock.__getitem__()' id='4385349968'>
해당 메소드가 처음으로 호출 될 때 MagicMock에 추가 된 메소드를 "볼"수 있습니다.
>>> magic1 = MagicMock()
>>> dir(magic1)
['assert_any_call', 'assert_called_once_with', ...]
>>> int(magic1)
1
>>> dir(magic1)
['__int__', 'assert_any_call', 'assert_called_once_with', ...]
>>> len(magic1)
0
>>> dir(magic1)
['__int__', '__len__', 'assert_any_call', 'assert_called_once_with', ...]
그렇다면 MagicMock을 항상 사용하지 않는 이유는 무엇입니까?
다시 당신에게 질문은 : 당신은 기본 마술 방법 구현에 괜찮습니까? 예를 들어, mocked_object[1]
실수하지 않아도 괜찮 습니까? 매직 메소드 구현으로 인해 의도하지 않은 결과가 발생해도 괜찮습니까?
이 질문에 대한 대답이 예라면 MagicMock을 사용하십시오. 그렇지 않으면 Mock을 고수하십시오.
이것은 파이썬의 공식 문서가 말하는 것입니다 :
이러한 대부분의 예에서 Mock 클래스와 MagicMock 클래스는 서로 바꿔 사용할 수 있습니다. MagicMock이 더 유능한 클래스이기 때문에 기본적으로 사용하기에 적합한 클래스입니다.
단순함 Mock
이 다음보다 유용 할 수 있는 또 다른 특별한 경우를 발견했습니다 MagicMock
.
In [1]: from unittest.mock import Mock, MagicMock, ANY
In [2]: mock = Mock()
In [3]: magic = MagicMock()
In [4]: mock.foo == ANY
Out[4]: True
In [5]: magic.foo == ANY
Out[5]: False
ANY
예를 들어 모의를 사용하여 일부 값을 계산하는 두 사전 사이의 거의 모든 키를 비교하는 것과 비교하면 유용 할 수 있습니다.
다음을 사용하는 경우 유효합니다 Mock
.
self.assertDictEqual(my_dict, {
'hello': 'world',
'another': ANY
})
그것은을 올릴 때 AssertionError
사용한 한 경우MagicMock