Assert a function/method was not called using Mock

136,678

Solution 1

This should work for your case;

assert not my_var.called, 'method should not have been called'

Sample;

>>> mock=Mock()
>>> mock.a()
<Mock name='mock.a()' id='4349129872'>
>>> assert not mock.b.called, 'b was called and should not have been'
>>> assert not mock.a.called, 'a was called and should not have been'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: a was called and should not have been

Solution 2

Though an old question, I would like to add that currently mock library (backport of unittest.mock) supports assert_not_called method.

Just upgrade yours;

pip install mock --upgrade

Solution 3

With python >= 3.5 you can use mock_object.assert_not_called().

Solution 4

You can check the called attribute, but if your assertion fails, the next thing you'll want to know is something about the unexpected call, so you may as well arrange for that information to be displayed from the start. Using unittest, you can check the contents of call_args_list instead:

self.assertItemsEqual(my_var.call_args_list, [])

When it fails, it gives a message like this:

AssertionError: Element counts were not equal:
First has 0, Second has 1:  call('first argument', 4)

Solution 5

When you test using class inherits unittest.TestCase you can simply use methods like:

  • assertTrue
  • assertFalse
  • assertEqual

and similar (in python documentation you find the rest).

In your example we can simply assert if mock_method.called property is False, which means that method was not called.

import unittest
from unittest import mock

import my_module

class A(unittest.TestCase):
    def setUp(self):
        self.message = "Method should not be called. Called {times} times!"

    @mock.patch("my_module.method_to_mock")
    def test(self, mock_method):
        my_module.method_to_mock()

        self.assertFalse(mock_method.called,
                         self.message.format(times=mock_method.call_count))
Share:
136,678

Related videos on Youtube

Gerard
Author by

Gerard

Lover of music, food and open source. Always looking for something new to learn, whatever the subject.

Updated on February 02, 2022

Comments

  • Gerard
    Gerard over 2 years

    I'm using the Mock library to test my application, but I want to assert that some function was not called. Mock docs talk about methods like mock.assert_called_with and mock.assert_called_once_with, but I didn't find anything like mock.assert_not_called or something related to verify mock was NOT called.

    I could go with something like the following, though it doesn't seem cool nor pythonic:

    def test_something:
        # some actions
        with patch('something') as my_var:
            try:
                # args are not important. func should never be called in this test
                my_var.assert_called_with(some, args)
            except AssertionError:
                pass  # this error being raised means it's ok
        # other stuff
    

    Any ideas how to accomplish this?

    • Martin
      Martin about 7 years
      As @Ahmet points out in his answer, assert_not_called is now supported, also in the backport (docs.python.org/3/library/…).
  • Nathan Arthur
    Nathan Arthur over 9 years
    Does this answer require Django? I'm getting an error: AttributeError: MockCallable instance has no attribute 'called'
  • Joachim Isaksson
    Joachim Isaksson over 9 years
    @NathanArthur Hm, I don't think so, after sudo easy_install -U mock and from mock import Mock on MacOS, the above runs without a hitch. Never installed Django :)
  • Nathan Arthur
    Nathan Arthur over 9 years
    Hmm. That's odd. I'm running Python 2.7.1 and am using unittest and from mock import Mock with Python Mock 0.1.0 for my tests. Does any of that sound problematic?
  • 0xc0de
    0xc0de almost 9 years
    I'm mocking a callable class from another module, so it looks like module_to_test.another_module.class = mock.Mock(), can you confirm this doesn't remember calls across different test cases (unittest.TestCase instances)? I think the call count doesn't reset in this case
  • Clint Eastwood
    Clint Eastwood almost 3 years
    I cannot understand why this answer has so few votes.... to me, this is the right answer!
  • Hunter_71
    Hunter_71 almost 3 years
    Thanks @ClintEastwood, hope that helps! :)
  • MrAbelash
    MrAbelash over 2 years
    Use assert_not_called method