Assert that a method was called in a Python unit test

Suppose I have the following code in a Python unit test:

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

Is there an easy way to assert that a particular method (in my case aw.Clear()) was called during the second line of the test? e.g. is there something like this:

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

I use Mock (which is now unittest.mock on py3.3+) for this:

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)

For your case, it could look like this:

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 supports quite a few useful features, including ways to patch an object or module, as well as checking that the right thing was called, etc etc.

Caveat emptor! (Buyer beware!)

If you mistype assert_called_with (to assert_called_once or assert_called_wiht) your test may still run, as Mock will think this is a mocked function and happily go along, unless you use autospec=true. For more info read assert_called_once: Threat or Menace.


Yes if you are using Python 3.3+. You can use the built-in unittest.mock to assert method called. For Python 2.6+ use the rolling backport Mock, which is the same thing.

Here is a quick example in your case:

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

I'm not aware of anything built-in. It's pretty simple to implement:

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

This requires that the object itself won't modify self.b, which is almost always true.