programing

Python 단위 테스트에서 메서드가 호출되었다고 주장합니다.

lastmoon 2023. 7. 21. 21:52
반응형

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은 객체나 모듈을 패치하는 방법뿐만 아니라 올바른 것이 호출되었는지 확인하는 등의 몇 가지 유용한 기능을 지원합니다.

청소부를 조심하세요! (구매자 주의!)

잘못 입력한 경우assert_called_with(행)assert_called_once아니면 두 글자만 바꿔도 됩니다.assert_called_wiht) 당신의 테스트는 여전히 실행될 수 있습니다. Mock은 이것이 조롱당한 기능이라고 생각하고 행복하게 진행될 것이기 때문입니다. 당신이 사용하지 않는 한.autospec=true자세한 내용은 assert_called_once를 참조하십시오. 위협 또는 위협.

Python 3.3+를 사용하는 경우 예.기본 제공을 사용하여 호출된 메서드를 어설션할 수 있습니다.Python 2.6+의 경우 롤링 백포트를 사용하는데, 이는 동일합니다.

다음은 귀하의 사례에 대한 간단한 예입니다.

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를 수정하지 않아야 하는데, 이는 거의 항상 사실입니다.

네, 개요는 말씀드릴 수 있지만, 제 파이썬이 좀 녹슬어서 너무 바빠서 자세히 설명할 수가 없습니다.

기본적으로 원본을 호출하는 메서드에 프록시를 넣어야 합니다. 예를 들어 다음과 같습니다.

 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)

호출 가능에 대한 이 StackOverflow 답변은 위의 내용을 이해하는 데 도움이 될 수 있습니다.

자세한 내용:

답변은 받아들여졌지만, 글렌과의 흥미로운 토론과 몇 분간의 여유 시간 때문에, 저는 제 답변을 확대하고 싶었습니다.

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

놀려도 됩니다.aw.Clear수동으로 또는 피목스와 같은 테스트 프레임워크를 사용합니다.수동으로 다음과 같은 작업을 수행할 수 있습니다.

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

Pymox를 사용하면 다음과 같이 수행할 수 있습니다.

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

반응형