[TIP] use mock to test a call with a side_effect that modifies a mutable arg?

Gregory P. Smith greg at krypto.org
Tue Dec 27 17:49:11 PST 2011


I'm used to using pymox for most of my mocking but figured I'd give mock a
try on some new code.

One thing I just ran into:

mything = Mock(spec=other_function_to_stub_out)
... replace other_function_to_stub_out with mything ...
mything.return_value = (2, 3)
def _set_deps(mydict): mydict['deps'] = ['TEST']
mything.side_effect = _set_deps
ThingBeingTested(copy.deepcopy(example_input))
self.assertEqual(mything.call_count, 1)
self.assertEqual(mything.call_args, example_input)

The last assert raises error when example_input does not already contain
the modification made my the side_effect.

The mything.side_effect modifies the dictionary argument passed to mything
when it was called, that makes sense.  But I was hoping that call_args
would be a snapshot of the args at call time (a copy.deepcopy of it) rather
than having had the side_effect applied to it.

Is this intentional?

I can update my side_effect function to include an assert on mydict
instead.  But it wasn't the behavior I expected even though I can see why
it probably happens even without digging into the mock sources.

In a pymox world this would've been written similar to:

mything(example_input).AndReturn((2, 3)
self.mox.ReplayAll()
ThingBeingTested(copy.deepcopy(example_input))
self.mox.VerifyAll()

-gps
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.idyll.org/pipermail/testing-in-python/attachments/20111227/2888a295/attachment.htm>


More information about the testing-in-python mailing list