Python 단위 테스트에서 메서드가 호출되었는지 확인
Python 단위 테스트에 다음 코드가 있다고 가정합니다.
aw = aps.Request("nv1")
aw2 = aps.Request("nv2", aw)
aw.Clear()
테스트의 두 번째 줄 에서 특정 메서드 (내 경우 )가 호출 되었다고 쉽게 주장 할 수있는 방법이 있습니까? 예를 들면 다음과 같습니다.
#pseudocode:
assertMethodIsCalled(aw.Clear, lambda: aps.Request("nv2", aw))
나는 이것을 위해 Mock (현재 py3.3 +에서 unittest.mock 임)을 사용합니다.
from mock import patch
from PyQt4 import Qt
@patch.object(Qt.QMessageBox, 'aboutQt')
def testShowAboutQt(self, mock):
self.win.actionAboutQt.trigger()
self.assertTrue(mock.called)
귀하의 경우 다음과 같이 보일 수 있습니다.
import mock
from mock import patch
def testClearWasCalled(self):
aw = aps.Request("nv1")
with patch.object(aw, 'Clear') as mock:
aw2 = aps.Request("nv2", aw)
mock.assert_called_with(42) # or mock.assert_called_once_with(42)
Mock은 객체 또는 모듈을 패치하는 방법, 올바른 것이 호출되었는지 확인하는 방법 등을 포함하여 몇 가지 유용한 기능을 지원합니다.
주의 사항! (구매자는 조심하십시오!)
를 사용하지 않는 한 Mock은 이것이 모의 함수라고 생각하고 행복하게 진행할 것이므로 assert_called_with
( assert_called_once
또는에 assert_called_wiht
) 잘못 입력 해도 테스트가 계속 실행될 수 있습니다 autospec=true
. 자세한 내용은 assert_called_once : Threat 또는 Menace를 읽어 보세요 .
예, Python 3.3 이상을 사용하는 경우. 내장 된 unittest.mock
메소드를 사용하여 호출 된 메소드를 주장 할 수 있습니다 . Python 2.6 이상에서는 동일한 롤링 백 포트를 사용합니다 Mock
.
다음은 귀하의 경우에 대한 간단한 예입니다.
from unittest.mock import MagicMock
aw = aps.Request("nv1")
aw.Clear = MagicMock()
aw2 = aps.Request("nv2", aw)
assert aw.Clear.called
내장 된 항목을 인식하지 못합니다. 구현하는 것은 매우 간단합니다.
class assertMethodIsCalled(object):
def __init__(self, obj, method):
self.obj = obj
self.method = method
def called(self, *args, **kwargs):
self.method_called = True
self.orig_method(*args, **kwargs)
def __enter__(self):
self.orig_method = getattr(self.obj, self.method)
setattr(self.obj, self.method, self.called)
self.method_called = False
def __exit__(self, exc_type, exc_value, traceback):
assert getattr(self.obj, self.method) == self.called,
"method %s was modified during assertMethodIsCalled" % self.method
setattr(self.obj, self.method, self.orig_method)
# If an exception was thrown within the block, we've already failed.
if traceback is None:
assert self.method_called,
"method %s of %s was not called" % (self.method, self.obj)
class test(object):
def a(self):
print "test"
def b(self):
self.a()
obj = test()
with assertMethodIsCalled(obj, "a"):
obj.b()
이를 위해서는 객체 자체가 self.b를 수정하지 않아야하며 이는 거의 항상 사실입니다.
예, 개요를 드릴 수는 있지만 제 Python은 약간 녹슬 어서 자세히 설명하기에는 너무 바쁩니다.
기본적으로 원본을 호출 할 메서드에 프록시를 넣어야합니다. 예 :
class fred(object):
def blog(self):
print "We Blog"
class methCallLogger(object):
def __init__(self, meth):
self.meth = meth
def __call__(self, code=None):
self.meth()
# would also log the fact that it invoked the method
#example
f = fred()
f.blog = methCallLogger(f.blog)
This StackOverflow answer about callable may help you understand the above.
In more detail:
Although the answer was accepted, due to the interesting discussion with Glenn and having a few minutes free, I wanted to enlarge on my answer:
# helper class defined elsewhere
class methCallLogger(object):
def __init__(self, meth):
self.meth = meth
self.was_called = False
def __call__(self, code=None):
self.meth()
self.was_called = True
#example
class fred(object):
def blog(self):
print "We Blog"
f = fred()
g = fred()
f.blog = methCallLogger(f.blog)
g.blog = methCallLogger(g.blog)
f.blog()
assert(f.blog.was_called)
assert(not g.blog.was_called)
You can mock out aw.Clear
, either manually or using a testing framework like pymox. Manually, you'd do it using something like this:
class MyTest(TestCase):
def testClear():
old_clear = aw.Clear
clear_calls = 0
aw.Clear = lambda: clear_calls += 1
aps.Request('nv2', aw)
assert clear_calls == 1
aw.Clear = old_clear
Using pymox, you'd do it like this:
class MyTest(mox.MoxTestBase):
def testClear():
aw = self.m.CreateMock(aps.Request)
aw.Clear()
self.mox.ReplayAll()
aps.Request('nv2', aw)
참고URL : https://stackoverflow.com/questions/3829742/assert-that-a-method-was-called-in-a-python-unit-test
'Programing' 카테고리의 다른 글
저장 프로 시저, 함수 및 루틴의 차이점은 무엇입니까? (0) | 2020.10.29 |
---|---|
Doctrine 쿼리에서 null 값을 필터로 지정하는 방법은 무엇입니까? (0) | 2020.10.29 |
기본 PDO 가져 오기 모드를 설정할 수 있습니까? (0) | 2020.10.29 |
.git 폴더를 어떻게 정리할 수 있습니까? (0) | 2020.10.29 |
OpenGL과 OpenCL, 무엇을 선택해야하며 그 이유는 무엇입니까? (0) | 2020.10.29 |