Saya menggunakan Mock (yang sekarang unittest.mock di py3.3 +) untuk ini:
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)
Untuk kasus Anda, ini akan terlihat seperti ini:
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)
Mock mendukung beberapa fitur yang berguna, termasuk cara untuk menambal objek atau modul, serta memeriksa apakah panggilan yang benar, dll.
Caveat emptor! (Pembeli berhati-hatilah!)
Jika Anda salah mengetik assert_called_with
( assert_called_once
atau assert_called_wiht
) pengujian Anda mungkin masih berjalan, karena Mock akan mengira ini adalah fungsi yang diolok-olok dan dengan senang hati berjalan, kecuali Anda menggunakannya autospec=true
. Untuk info lebih lanjut baca assert_called_once: Ancaman atau Ancaman .
Ya jika Anda menggunakan Python 3.3+. Anda dapat menggunakan
unittest.mock
metode bawaan untuk menegaskan yang dipanggil. Untuk Python 2.6+ gunakan rolling backportMock
, yang merupakan hal yang sama.Berikut adalah contoh singkat dalam kasus Anda:
from unittest.mock import MagicMock aw = aps.Request("nv1") aw.Clear = MagicMock() aw2 = aps.Request("nv2", aw) assert aw.Clear.called
sumber
Saya tidak mengetahui apa pun yang ada di dalamnya. Ini cukup sederhana untuk diterapkan:
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()
Ini mensyaratkan bahwa objek itu sendiri tidak akan memodifikasi self.b, yang hampir selalu benar.
sumber
Ya, saya bisa memberi Anda garis besarnya tetapi Python saya agak berkarat dan saya terlalu sibuk untuk menjelaskan secara detail.
Pada dasarnya, Anda perlu menempatkan proxy dalam metode yang akan memanggil yang asli, misalnya:
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)
Ini jawaban StackOverflow tentang callable dapat membantu Anda memahami di atas.
Lebih detail:
Meskipun jawabannya diterima, karena diskusi yang menarik dengan Glenn dan memiliki waktu luang beberapa menit, saya ingin memperbesar jawaban saya:
# 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)
sumber
Anda dapat membuat tiruan
aw.Clear
, baik secara manual atau menggunakan kerangka pengujian seperti pymox . Secara manual, Anda akan melakukannya menggunakan sesuatu seperti ini: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
Menggunakan pymox, Anda akan melakukannya seperti ini:
class MyTest(mox.MoxTestBase): def testClear(): aw = self.m.CreateMock(aps.Request) aw.Clear() self.mox.ReplayAll() aps.Request('nv2', aw)
sumber