Hướng dẫn python check if method was called - python kiểm tra xem phương thức có được gọi không

Giả sử tôi có mã sau trong bài kiểm tra đơn vị Python:

aw = aps.Request("nv1")
aw2 = aps.Request("nv2", aw)

Có một cách dễ dàng để khẳng định rằng một phương pháp cụ thể (trong trường hợp của tôi

#pseudocode:
assertMethodIsCalled(aw.Clear, lambda: aps.Request("nv2", aw))
0) đã được gọi trong dòng thứ hai của bài kiểm tra? ví dụ. Có một cái gì đó như thế này:

#pseudocode:
assertMethodIsCalled(aw.Clear, lambda: aps.Request("nv2", aw))

Hỏi ngày 30 tháng 9 năm 2010 lúc 10:32Sep 30, 2010 at 10:32

Hướng dẫn python check if method was called - python kiểm tra xem phương thức có được gọi không

Mark Heathmark HeathMark Heath

47.5K29 Huy hiệu vàng134 Huy hiệu bạc193 Huy hiệu Đồng29 gold badges134 silver badges193 bronze badges

Tôi sử dụng Mock (hiện đang unittest.mock trên py3.3+) cho điều này:

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)

Đối với trường hợp của bạn, nó có thể trông như thế này:

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 hỗ trợ khá nhiều tính năng hữu ích, bao gồm các cách để vá một đối tượng hoặc mô -đun, cũng như kiểm tra xem điều đúng được gọi là, v.v.

Emptor caveat! (Người mua hãy cẩn thận!) (Buyer beware!)

Nếu bạn nhầm lẫn

#pseudocode:
assertMethodIsCalled(aw.Clear, lambda: aps.Request("nv2", aw))
1 (đến
#pseudocode:
assertMethodIsCalled(aw.Clear, lambda: aps.Request("nv2", aw))
2 hoặc
#pseudocode:
assertMethodIsCalled(aw.Clear, lambda: aps.Request("nv2", aw))
3) Bài kiểm tra của bạn vẫn có thể chạy, vì Mock sẽ nghĩ rằng đây là một chức năng bị chế giễu và vui vẻ đi cùng, trừ khi bạn sử dụng
#pseudocode:
assertMethodIsCalled(aw.Clear, lambda: aps.Request("nv2", aw))
4. Để biết thêm thông tin, hãy đọc ASSERT_CALLED_ONCE: Đe dọa hoặc đe dọa.

Hướng dẫn python check if method was called - python kiểm tra xem phương thức có được gọi không

RDA

20.1k6 Huy hiệu vàng35 Huy hiệu bạc46 Huy hiệu đồng6 gold badges35 silver badges46 bronze badges

Đã trả lời ngày 19 tháng 1 năm 2011 lúc 10:59Jan 19, 2011 at 10:59

MackemackeMacke

24.2K7 Huy hiệu vàng80 Huy hiệu bạc116 Huy hiệu đồng7 gold badges80 silver badges116 bronze badges

8

Có nếu bạn đang sử dụng Python 3.3+. Bạn có thể sử dụng

#pseudocode:
assertMethodIsCalled(aw.Clear, lambda: aps.Request("nv2", aw))
5 tích hợp để khẳng định phương thức được gọi là. Đối với Python 2.6+, hãy sử dụng backport cuộn
#pseudocode:
assertMethodIsCalled(aw.Clear, lambda: aps.Request("nv2", aw))
6, đó là điều tương tự.

Đây là một ví dụ nhanh trong trường hợp của bạn:

from unittest.mock import MagicMock
aw = aps.Request("nv1")
aw.Clear = MagicMock()
aw2 = aps.Request("nv2", aw)
assert aw.Clear.called

Hướng dẫn python check if method was called - python kiểm tra xem phương thức có được gọi không

Đã trả lời ngày 8 tháng 8 năm 2016 lúc 16:13Aug 8, 2016 at 16:13

DevydevyDevy

9.3437 Huy hiệu vàng60 Huy hiệu bạc57 Huy hiệu Đồng7 gold badges60 silver badges57 bronze badges

Tôi không biết bất cứ điều gì tích hợp. Nó khá đơn giản để thực hiện:

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

Điều này đòi hỏi chính đối tượng sẽ không sửa đổi bản thân.b, điều này hầu như luôn luôn đúng.

Đã trả lời ngày 30 tháng 9 năm 2010 lúc 10:49Sep 30, 2010 at 10:49

Glenn Maynardglenn MaynardGlenn Maynard

54.4K10 Huy hiệu vàng117 Huy hiệu bạc131 Huy hiệu đồng10 gold badges117 silver badges131 bronze badges

2

Vâng, tôi có thể cung cấp cho bạn phác thảo nhưng con trăn của tôi hơi gỉ và tôi quá bận để giải thích chi tiết.

Về cơ bản, bạn cần đặt một proxy vào phương thức sẽ gọi bản gốc, ví dụ:

 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)

Câu trả lời của StackOverflow về Callable có thể giúp bạn hiểu những điều trên.

Chi tiết hơn:

Mặc dù câu trả lời đã được chấp nhận, do cuộc thảo luận thú vị với Glenn và có một vài phút miễn phí, tôi muốn mở rộng câu trả lời của mình:

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

Đã trả lời ngày 30 tháng 9 năm 2010 lúc 10:46Sep 30, 2010 at 10:46

Andy Dentandy DentAndy Dent

17.2k6 Huy hiệu vàng84 Huy hiệu bạc113 Huy hiệu đồng6 gold badges84 silver badges113 bronze badges

4

Bạn có thể chế giễu

#pseudocode:
assertMethodIsCalled(aw.Clear, lambda: aps.Request("nv2", aw))
7, bằng tay hoặc sử dụng khung thử nghiệm như pymox. Theo cách thủ công, bạn sẽ làm điều đó bằng cách sử dụng một cái gì đó như thế này:

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

Sử dụng pymox, bạn sẽ làm như thế này:

class MyTest(mox.MoxTestBase):
  def testClear():
    aw = self.m.CreateMock(aps.Request)
    aw.Clear()
    self.mox.ReplayAll()
    aps.Request('nv2', aw)

Đã trả lời ngày 30 tháng 9 năm 2010 lúc 10:43Sep 30, 2010 at 10:43

Max Shawabkehmax ShawabkehMax Shawabkeh

36,9k9 Huy hiệu vàng81 Huy hiệu bạc91 Huy hiệu Đồng9 gold badges81 silver badges91 bronze badges

1

Làm thế nào để bạn kiểm tra xem một phương thức đã được gọi bằng Python?

Hàm python callable () hàm callable () trả về true nếu đối tượng được chỉ định có thể gọi được, nếu không nó sẽ trả về sai.callable() Function The callable() function returns True if the specified object is callable, otherwise it returns False.

Sự khác biệt giữa Mock và Magicmock là gì?

Vậy sự khác biệt giữa họ là gì?MagicMock là một lớp con của Mock.Nó chứa tất cả các phương pháp ma thuật được tạo sẵn và sẵn sàng sử dụng (ví dụ: __str__, __len__, v.v.).Do đó, bạn nên sử dụng MagicMock khi bạn cần Phương pháp ma thuật và chế giễu nếu bạn không cần chúng.MagicMock is a subclass of Mock . It contains all magic methods pre-created and ready to use (e.g. __str__ , __len__ , etc.). Therefore, you should use MagicMock when you need magic methods, and Mock if you don't need them.

Side_ Hiệu ứng trong Mock Python là gì?

Side_Effect: Một chức năng được gọi bất cứ khi nào giả được gọi.Xem thuộc tính Side_Effect.Hữu ích để nâng cao các ngoại lệ hoặc thay đổi một cách tự động các giá trị trả về.Hàm được gọi với cùng một đối số với giả và trừ khi nó trả về mặc định, giá trị trả về của hàm này được sử dụng làm giá trị trả về.A function to be called whenever the Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT , the return value of this function is used as the return value.

Mock pytest là gì?

Trong pytest, chế giễu có thể thay thế giá trị trả về của một hàm trong một hàm.Điều này rất hữu ích để kiểm tra hàm mong muốn và thay thế giá trị trả về của hàm lồng nhau trong hàm mong muốn mà chúng tôi đang thử nghiệm.