Search code examples
pythonpython-3.xunit-testingmockingmagicmock

python check if a method is called without mocking it away


class A():
    def tmp(self):
        print("hi")

def b(a):
    a.tmp()

To check if tmp method is called in b, the recommended way is

a = A()
a.tmp = MagicMock()
b(a)
a.tmp.assert_called()

But tmp here is being mocked away and is not resulting in a "hi" getting printed.

I would want my unit test to check if method tmp is called without mocking it away.

Is this possible?

I know this is not a standard thing to expect when writing unitests. But my use case (which is bit tricky) requires this.


Solution

  • You can set the Mock.side_effect to be the original method.

    from unittest.mock import MagicMock
    
    class A():
        def tmp(self):
            print("hi")
    
    def b(a):
        a.tmp()
    
    a = A()
    a.tmp = MagicMock(side_effect=a.tmp)
    b(a)
    a.tmp.assert_called()
    

    When side_effect is a function (or a bound method in this case, which is a kind of function), calling the Mock will also call the side_effect with the same arguments.

    The Mock() call will return whatever the side_effect returns, unless it returns the unnittest.mock.DEFAULT singleton. Then it will return Mock.return_value instead.