Saturday, June 08, 2013

Assert a method is not called using Mox

Let's say you want to unit test a function and make sure that another function is not called at any point during the routine.

To do it, simply stub out the function you want to assert isn't called, and do not record a call to it before putting the mocks into replay mode.

Here's some example code:

import unittest

import mox


class Mystery(object):
    def want(self):
        pass

    def do_not_want(self):
        pass

    def func(self):
        self.want()


class TestIt(unittest.TestCase):
    def test(self):
        mox = mox.Mox()
        
        m = Mystery()

        # stub out the functions you're interested in verifying
        mox.StubOutWithMock(m, 'want')
        mox.StubOutWithMock(m, 'do_not_want')

        # record calls to stubbed out functions that are
        # expected to be called, in the order expected,
        # as many times as expected
        m.want()

        # set the mocks to replay mode
        mox.ReplayAll()

        # call the function you want to unit test
        m.func()

        # verify the expected calls were made, and the
        # unexpected calls were not made
        mox.VerifyAll()

if __name__ == '__main__':
    unittest.main()

The above code yields the result:

.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

If we update class Mystery to:

class Mystery(object):
    def want(self):
        pass

    def do_not_want(self):
        pass

    def func(self):
        self.want()
        self.do_not_want()

We get this result instead:

F
======================================================================
FAIL: test (__main__.TestIt)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "notcalled.py", line 28, in test
    m.func()
  File "notcalled.py", line 14, in func
    self.do_not_want()
  File "/Library/Python/2.6/site-packages/mox.py", line 765, in __call__
    return mock_method(*params, **named_params)
  File "/Library/Python/2.6/site-packages/mox.py", line 1002, in __call__
    expected_method = self._VerifyMethodCall()
  File "/Library/Python/2.6/site-packages/mox.py", line 1049, in _VerifyMethodCall
    expected = self._PopNextMethod()
  File "/Library/Python/2.6/site-packages/mox.py", line 1035, in _PopNextMethod
    raise UnexpectedMethodCallError(self, None)
UnexpectedMethodCallError: Unexpected method call do_not_want.__call__() -> None

----------------------------------------------------------------------
Ran 1 test in 0.008s

FAILED (failures=1)

13 comments:

  1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a Front end developer Node js Training in Chennai . learn from or Javascript Online Training from India. Nowadays JavaScript has tons of job opportunities on various vertical industry. JavaScript Training in Chennai

    ReplyDelete
  2. Great Post!
    Thanks a lot for sharing!
    I found this blog to be very useful!!
    DevOps training in Bangalore

    ReplyDelete
  3. Niche blogs cater to specific interests and hobbies Gutscheincode 2023 creating tight-knit communities where enthusiasts can find like-minded individuals and valuable resources.

    ReplyDelete