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

Michael Foord fuzzyman at voidspace.org.uk
Wed Dec 28 05:35:23 PST 2011

On 28 Dec 2011, at 01:49, Gregory P. Smith wrote:

> 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)

And note that the assert is better written as:


If you're looking to save lines you can also set return_value (and side_effect) in the Mock constructor...

All the best,

Michael Foord

> 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
> _______________________________________________
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
> http://lists.idyll.org/listinfo/testing-in-python


May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing 

More information about the testing-in-python mailing list