나는 파이썬과 함께 mock 을 사용 하고 있으며 그 두 가지 접근법 중 어느 것이 더 나은지 궁금합니다 (읽기 : 더 파이썬).
방법 1 : 모의 객체를 만들고 사용하십시오. 코드는 다음과 같습니다.
def test_one (self):
mock = Mock()
mock.method.return_value = True
self.sut.something(mock) # This should called mock.method and checks the result.
self.assertTrue(mock.method.called)
방법 2 : 패치를 사용하여 모의를 만듭니다. 코드는 다음과 같습니다.
@patch("MyClass")
def test_two (self, mock):
instance = mock.return_value
instance.method.return_value = True
self.sut.something(instance) # This should called mock.method and checks the result.
self.assertTrue(instance.method.called)
두 방법 모두 동일한 작업을 수행합니다. 차이점이 확실하지 않습니다.
누구든지 나를 깨달을 수 있습니까?
답변
mock.patch
와는 매우 다른 동물 mock.Mock
입니다. 클래스를 모의 객체로 patch
대체 하고 모의 인스턴스로 작업 할 수 있습니다. 이 스 니펫을 살펴보십시오.
>>> class MyClass(object):
... def __init__(self):
... print 'Created MyClass@{0}'.format(id(self))
...
>>> def create_instance():
... return MyClass()
...
>>> x = create_instance()
Created MyClass@4299548304
>>>
>>> @mock.patch('__main__.MyClass')
... def create_instance2(MyClass):
... MyClass.return_value = 'foo'
... return create_instance()
...
>>> i = create_instance2()
>>> i
'foo'
>>> def create_instance():
... print MyClass
... return MyClass()
...
>>> create_instance2()
<mock.Mock object at 0x100505d90>
'foo'
>>> create_instance()
<class '__main__.MyClass'>
Created MyClass@4300234128
<__main__.MyClass object at 0x100505d90>
patch
MyClass
호출하는 함수에서 클래스 사용을 제어 할 수있는 방식으로 대체 됩니다. 클래스를 패치하면 클래스에 대한 참조가 모의 인스턴스로 완전히 대체됩니다.
mock.patch
일반적으로 테스트 내부에 클래스의 새 인스턴스를 만드는 무언가를 테스트 할 때 사용됩니다. mock.Mock
인스턴스가 더 명확하고 선호됩니다. self.sut.something
메서드가 인스턴스를 MyClass
매개 변수로받는 대신 인스턴스를 만든 경우 mock.patch
여기에 적합합니다.
답변
이것에 대한 YouTube 비디오 가 있습니다.
짧은 대답 : mock
조롱하고 싶은 것을 전달할 때 사용 하고 patch
그렇지 않은 경우 사용하십시오. 두 가지 중에서 mock은 적절한 종속성 주입으로 코드를 작성하고 있음을 의미하기 때문에 강력하게 선호됩니다.
어리석은 예 :
# Use a mock to test this.
my_custom_tweeter(twitter_api, sentence):
sentence.replace('cks','x') # We're cool and hip.
twitter_api.send(sentence)
# Use a patch to mock out twitter_api. You have to patch the Twitter() module/class
# and have it return a mock. Much uglier, but sometimes necessary.
my_badly_written_tweeter(sentence):
twitter_api = Twitter(user="XXX", password="YYY")
sentence.replace('cks','x')
twitter_api.send(sentence)