断言在Python单元tes中调用了方法

2024-06-06 03:06:28 发布

您现在位置:Python中文网/ 问答频道 /正文

假设在Python单元测试中有以下代码:

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

有没有一种简单的方法可以断言在测试的第二行调用了特定的方法(在我的例子中是aw.Clear())?e、 g.有这样的东西吗:

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

Tags: 方法lambda代码request断言单元测试例子clear
3条回答

我不知道有什么内在的东西。实现起来相当简单:

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,这几乎总是正确的。

是的,如果您使用的是Python3.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

我使用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支持很多有用的特性,包括修补对象或模块的方法,以及检查是否调用了正确的对象等

Caveat emptor!(买家当心!)

如果您错误地输入assert_called_with(到assert_called_onceassert_called_wiht),那么您的测试可能仍然在运行,因为Mock会认为这是一个模拟函数,并且很高兴继续,除非您使用autospec=true。有关详细信息,请阅读assert_called_once: Threat or Menace

相关问题 更多 >