developer tip

클래스 조롱 : Mock () 또는 patch ()?

optionbox 2020. 8. 12. 08:08
반응형

클래스 조롱 : Mock () 또는 patch ()?


나는 파이썬과 함께 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>

patchMyClass호출하는 함수에서 클래스 사용을 제어 할 수있는 방식으로 대체 됩니다. 클래스를 패치하면 클래스에 대한 참조가 모의 인스턴스로 완전히 대체됩니다.

mock.patch is usually used when you are testing something that creates a new instance of a class inside of the test. mock.Mock instances are clearer and are preferred. If your self.sut.something method created an instance of MyClass instead of receiving an instance as a parameter, then mock.patch would be appropriate here.


I've got a YouTube video on this.

Short answer: Use mock when you're passing in the thing that you want mocked, and patch if you're not. Of the two, mock is strongly preferred because it means you're writing code with proper dependency injection.

Silly example:

# 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)

참고URL : https://stackoverflow.com/questions/8180769/mocking-a-class-mock-or-patch

반응형