evolution
evolution

Reputation: 4752

Python Mock Delay side_effect valuation

Is there any way to delay the evaluation of a Mock side_effect.

def mockfunc(wheel):
    wheel.rubber = soft

wheel.make = Mock(side_effect=mockfunc(wheel)))

The problem here is that I'm trying to replace the 'wheel.make' method such that when it is called under test, mockfunc is instead called and one of the wheel attributes is set instead of running the usual method.

Thing is - when I set the side_effect, the mockfunc call happens immediately, The rubber attribute is set to soft. I don't want this to happen until the method wheel.make is called.

Upvotes: 0

Views: 2428

Answers (1)

Michele d'Amico
Michele d'Amico

Reputation: 23771

According to side_effect documentation it should be a callable, an iterable or an exception (class or object). Moreover I guess you want to replace a unboundmethod make in wheel's Class: to do these kind of patching you should use patch or patch.object as context or decorator as described here.

Follow is a complete example of how to do it:

from mock import patch

class Wheel():
    def __init__(self):
        self.rubber = 0

    def make(self):
        self.rubber = 10

soft = 36
def mockfunc(wheel):
    wheel.rubber = soft

wheel = Wheel()
print("unpatched wheel before make rubber = {}".format(wheel.rubber))
wheel.make()
print("unpatched wheel after make rubber = {}".format(wheel.rubber))

with patch.object(Wheel, "make", side_effect=mockfunc, autospec=True):
    print("patched wheel before make rubber = {}".format(wheel.rubber))
    wheel.make()
    print("patched wheel after make rubber = {}".format(wheel.rubber))

And the output is

unpatched wheel before make rubber = 0
unpatched wheel after make rubber = 10
patched wheel before make rubber = 10
patched wheel after make rubber = 36

Upvotes: 1

Related Questions